ETH Price: $3,324.61 (+2.30%)
Gas: 3 Gwei

Token

FailFriends (FF)
 

Overview

Max Total Supply

509 FF

Holders

208

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
4 FF
0x5c62830cbe0a79dc4d3e389e88d2d866339506f4
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Contract

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity)

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

// File: ERC721A.sol


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

pragma solidity ^0.8.4;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        return _tokenApprovals[tokenId];
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        address approvedAddress = _tokenApprovals[tokenId];

        bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
            isApprovedForAll(from, _msgSenderERC721A()) ||
            approvedAddress == _msgSenderERC721A());

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

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        if (_addressToUint256(approvedAddress) != 0) {
            delete _tokenApprovals[tokenId];
        }

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

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

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

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

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

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

        address from = address(uint160(prevOwnershipPacked));
        address approvedAddress = _tokenApprovals[tokenId];

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

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

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

        // Clear approvals from the previous owner.
        if (_addressToUint256(approvedAddress) != 0) {
            delete _tokenApprovals[tokenId];
        }

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

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

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

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

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

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

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

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

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

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

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

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

            let length := sub(end, ptr)
            // Move the pointer 32 bytes leftwards to make room for the length.
            ptr := sub(ptr, 32)
            // Store the length.
            mstore(ptr, length)
        }
    }
}
// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol


// 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 proved to be a part of a Merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * _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}
     *
     * _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 the sibling nodes in `proof`,
     * consuming from one or the other at each step according to the instructions given by
     * `proofFlags`.
     *
     * _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}
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

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

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

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

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

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

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


// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_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) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

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

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

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

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

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


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

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

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


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

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

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

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

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

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

// File: @openzeppelin/contracts/token/ERC721/ERC721.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;








/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

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

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

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: address zero is not a valid owner");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: invalid token ID");
        return owner;
    }

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

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

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

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

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

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not token owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");

        _transfer(from, to, tokenId);
    }

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
        _safeTransfer(from, to, tokenId, data);
    }

    /**
     * @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.
     *
     * `data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);

        _afterTokenTransfer(address(0), to, tokenId);
    }

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

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);

        _afterTokenTransfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits an {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * 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, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;



/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
        return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * 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, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

// File: mdc.sol



pragma solidity ^0.8.0;





abstract contract ContextMixin {
    function msgSender()
        internal
        view
        returns (address payable sender)
    {
        if (msg.sender == address(this)) {
            bytes memory array = msg.data;
            uint256 index = msg.data.length;
            assembly {
                // Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
                sender := and(
                    mload(add(array, index)),
                    0xffffffffffffffffffffffffffffffffffffffff
                )
            }
        } else {
            sender = payable(msg.sender);
        }
        return sender;
    }
}


contract Contract is ERC721A, Ownable, ContextMixin {
    using Strings for uint256;

    /*Maximum number of NFTs*/
    uint256 public maxTokenSupply = 4444;   
    uint256 public freepresaleTokenSupply = 4444; //2000 in passato
    uint256 public reservedNFTs = 222; //150 in passato

    /*Price for each token during public sale*/       
    uint256 public price = 0.009 ether;
    uint256 public presalePrice = 0.0069 ether;
   
    /*Maximum number of tokens one can mint*/ 
    uint256 public freeMaxMint = 1;      
    uint256 public presaleMaxMint = 1; //2 in passato
    uint256 public publicsaleMaxMint = 2; //6 in passato   

    mapping(address=>bool) public hasMintedForFree;

    /*Whitelist merkle-root*/
    bytes32 public merkleroot_freeWL = bytes32(0);  //Free whitelist
    bytes32 public merklerootWL = bytes32(0);       //Waitlist

    string public baseURI;
    string public baseExtension;
    string public prerevealURI;
    
    bool public URIFinal;
    bool public saleActive;
    bool public presaleActive;
    bool public mintingActive;
    bool public reveal;
    
    
    constructor(string memory _initialBaseURI) ERC721A("FailFriends", "FF") {
        baseURI = _initialBaseURI;
        _safeMint(0x785C9c71337e5f31ea51135c6f78c436a5bda5c9, reservedNFTs);
    }   

    //FIRST TOKEN ID IS 1
    function _startTokenId() internal view virtual override(ERC721A) returns (uint256) {
      return 1;
    }

    /*URI management*/
    function toggleReveal() external onlyOwner{
        reveal = !reveal;
    }

    function setPreRevealURI(string memory uri) external onlyOwner{
        prerevealURI = uri;
    }

    /*Merkleroot management*/
    function setWLMerkleroot(bytes32 _merkleroot) external onlyOwner{
        merklerootWL = _merkleroot;
    }

    function setfreeWLMerkleroot(bytes32 _merkleroot) external onlyOwner{
        merkleroot_freeWL = _merkleroot;
    }

    /*URI functions*/
    function _baseURI() internal view virtual override returns (string memory) {
        return baseURI; 
    } 
    function setBaseURI(string memory _newBaseURI) external onlyOwner {
        require(!URIFinal, "URI is locked");
        baseURI = _newBaseURI;
    } 
    function setBaseExtension(string memory _newBaseExtension) external onlyOwner {
        require(!URIFinal, "URI is locked");
        baseExtension = _newBaseExtension;
    }
    function finalizeURI() external onlyOwner {
        URIFinal = true;
    }

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();


        if(reveal){
            return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId), ".json")) : '';
        }else{
            return prerevealURI;
        }
    }

    /*Sale management functions*/
    function toggleSaleActive() external onlyOwner {
        saleActive = !saleActive;
        presaleActive = false;
    }

    function togglePresaleActive() external onlyOwner{
        presaleActive = !presaleActive;
    }

    function toggleMintingActive() external onlyOwner{
        mintingActive = !mintingActive;
    }

    function setfreePresaleSupply(uint256 _supply) external onlyOwner{
        require(_supply >= totalSupply(), "New supply cannot be lower than current supply");
        freepresaleTokenSupply = _supply;
    }

    function setPublicsaleSupply(uint256 _supply) external onlyOwner{
        require(_supply >= totalSupply(), "New supply cannot be lower than current supply");
        maxTokenSupply = _supply;
    }
    function setfreePresaleMaxMint(uint256 _num) external onlyOwner{
        freeMaxMint = _num;
    }
    function setPresaleMaxMint(uint256 _num) external onlyOwner{
        presaleMaxMint = _num;
    }

    function setPublicsaleMaxMint(uint256 _num) external onlyOwner{
        publicsaleMaxMint = _num;
    }

    /*Ownership data*/
    function numberMinted(address owner) public view returns (uint256) {
        return _numberMinted(owner);
    }

    function getOwnershipData(uint256 tokenId) external view returns (TokenOwnership memory) {
        return _ownershipOf(tokenId);
    }

   
    /*Minting functions*/
    function freeMint(bytes32[] calldata _merkleproof) external{
        bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
        
        require(mintingActive, "Minting is not active yet.");
        require(!presaleActive, "Free mint is closed");
        require(!saleActive, "Free mint is closed");
        require(MerkleProof.verify(_merkleproof,merkleroot_freeWL,leaf), "You are not whitelisted.");
        require(_numberMinted(msg.sender) +1 <= freeMaxMint, "Cannot mint more tokens");
        require(totalSupply() + 1 <= freepresaleTokenSupply,"Presale supply is finished.");

        hasMintedForFree[msg.sender] = true; //stops user from minting during the waitlist phase
        _safeMint(msg.sender,1);


    }

    function presaleMint(uint256 _nftCount, bytes32[] calldata _merkleproof) external payable{
        bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
        
        require(mintingActive, "Minting is not active yet.");
        require(presaleActive, "Presale is not active yet.");
        require(!saleActive, "Presale is closed.");
        require(!hasMintedForFree[msg.sender], "Cannot mint : you have minted a NFT during the free mint phase.");
        require(MerkleProof.verify(_merkleproof,merklerootWL,leaf) || MerkleProof.verify(_merkleproof,merkleroot_freeWL,leaf), "You are not whitelisted.");
        require(_numberMinted(msg.sender) + _nftCount <= presaleMaxMint, "Cannot mint more tokens during presale.");
        require(totalSupply() + _nftCount <= maxTokenSupply,"Presale supply is finished.");
        require(msg.value == presalePrice * _nftCount, "Not enough funds for requested number of tokens.");

        _safeMint(msg.sender, _nftCount);

    }

    function publicMint(uint256 _nftCount) external payable{
        require(mintingActive, "Minting is not active yet.");
        require(saleActive, "Public sale has not started yet.");
        require(_numberMinted(msg.sender) + _nftCount <= publicsaleMaxMint, "Cannot mint more tokens during public sale.");
        require(totalSupply() + _nftCount <= maxTokenSupply,"Presale supply is finished.");
        require(msg.value == price * _nftCount, "Not enough funds for requested number of tokens.");

        _safeMint(msg.sender, _nftCount);


    }

    
    
    /*Withdraw function for contract owner */
    function withdraw() external payable onlyOwner {
        uint256 balance = address(this).balance;
        require(balance > 0, "Balance must be > 0");
        (bool success,) = payable(0x785C9c71337e5f31ea51135c6f78c436a5bda5c9).call{value:balance}("");
        require(success, "Failed to withdraw Ether");
    }

    /*Opensea integration*/
    function isApprovedForAll(
        address _owner,
        address _operator
    ) public override view returns (bool isOperator) {
      // if OpenSea's ERC721 Proxy Address is detected, auto-return true
        if (_operator == address(0x58807baD0B376efc12F5AD86aAc70E78ed67deaE)) {
            return true;
        }
        
        // otherwise, use the default ERC721.isApprovedForAll()
        return ERC721A.isApprovedForAll(_owner, _operator);
    }

    function _msgSender()
        internal
        override
        view
        returns (address sender)
    {
        return ContextMixin.msgSender();
    }

    
    
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_initialBaseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"URIFinal","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalizeURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"freeMaxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_merkleproof","type":"bytes32[]"}],"name":"freeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"freepresaleTokenSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getOwnershipData","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasMintedForFree","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"isOperator","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokenSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merklerootWL","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleroot_freeWL","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintingActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"prerevealURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleMaxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nftCount","type":"uint256"},{"internalType":"bytes32[]","name":"_merkleproof","type":"bytes32[]"}],"name":"presaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"presalePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nftCount","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"publicsaleMaxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reservedNFTs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reveal","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"_newBaseExtension","type":"string"}],"name":"setBaseExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setPreRevealURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"setPresaleMaxMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"setPublicsaleMaxMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supply","type":"uint256"}],"name":"setPublicsaleSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleroot","type":"bytes32"}],"name":"setWLMerkleroot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"setfreePresaleMaxMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supply","type":"uint256"}],"name":"setfreePresaleSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleroot","type":"bytes32"}],"name":"setfreeWLMerkleroot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleMintingActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"togglePresaleActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleReveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleSaleActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]

608060405261115c60095561115c600a5560de600b55661ff973cafa8000600c556618838370f34000600d556001600e556001600f5560026010556000801b6012556000801b6013553480156200005557600080fd5b5060405162005dd438038062005dd483398181016040528101906200007b919062000937565b6040518060400160405280600b81526020017f4661696c467269656e64730000000000000000000000000000000000000000008152506040518060400160405280600281526020017f46460000000000000000000000000000000000000000000000000000000000008152508160029080519060200190620000ff929190620007c0565b50806003908051906020019062000118929190620007c0565b50620001296200019960201b60201c565b60008190555050506200015162000145620001a260201b60201c565b620001be60201b60201c565b806014908051906020019062000169929190620007c0565b506200019273785c9c71337e5f31ea51135c6f78c436a5bda5c9600b546200028460201b60201c565b5062000c63565b60006001905090565b6000620001b9620002aa60201b62002cea1760201c565b905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620002a68282604051806020016040528060008152506200035d60201b60201c565b5050565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156200035657600080368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050600080369050905073ffffffffffffffffffffffffffffffffffffffff8183015116925050506200035a565b3390505b90565b600080549050600062000376856200062660201b60201c565b1415620003af576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000831415620003eb576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200040060008583866200063060201b60201c565b600160406001901b178302600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e16200046d600185146200063660201b60201c565b901b60a042901b62000485866200062660201b60201c565b1717600460008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b1462000596575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46200054260008784806001019550876200064060201b60201c565b62000579576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808210620004cb5782600054146200059057600080fd5b62000602565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a480821062000597575b816000819055505050620006206000858386620007b260201b60201c565b50505050565b6000819050919050565b50505050565b6000819050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026200066e620007b860201b60201c565b8786866040518563ffffffff1660e01b8152600401620006929493929190620009eb565b602060405180830381600087803b158015620006ad57600080fd5b505af1925050508015620006e157506040513d601f19601f82011682018060405250810190620006de919062000905565b60015b6200075f573d806000811462000714576040519150601f19603f3d011682016040523d82523d6000602084013e62000719565b606091505b5060008151141562000757576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b50505050565b600033905090565b828054620007ce9062000b5a565b90600052602060002090601f016020900481019282620007f257600085556200083e565b82601f106200080d57805160ff19168380011785556200083e565b828001600101855582156200083e579182015b828111156200083d57825182559160200191906001019062000820565b5b5090506200084d919062000851565b5090565b5b808211156200086c57600081600090555060010162000852565b5090565b600062000887620008818462000a68565b62000a3f565b905082815260208101848484011115620008a657620008a562000c29565b5b620008b384828562000b24565b509392505050565b600081519050620008cc8162000c49565b92915050565b600082601f830112620008ea57620008e962000c24565b5b8151620008fc84826020860162000870565b91505092915050565b6000602082840312156200091e576200091d62000c33565b5b60006200092e84828501620008bb565b91505092915050565b60006020828403121562000950576200094f62000c33565b5b600082015167ffffffffffffffff81111562000971576200097062000c2e565b5b6200097f84828501620008d2565b91505092915050565b620009938162000aba565b82525050565b6000620009a68262000a9e565b620009b2818562000aa9565b9350620009c481856020860162000b24565b620009cf8162000c38565b840191505092915050565b620009e58162000b1a565b82525050565b600060808201905062000a02600083018762000988565b62000a11602083018662000988565b62000a206040830185620009da565b818103606083015262000a34818462000999565b905095945050505050565b600062000a4b62000a5e565b905062000a59828262000b90565b919050565b6000604051905090565b600067ffffffffffffffff82111562000a865762000a8562000bf5565b5b62000a918262000c38565b9050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600062000ac78262000afa565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b8381101562000b4457808201518184015260208101905062000b27565b8381111562000b54576000848401525b50505050565b6000600282049050600182168062000b7357607f821691505b6020821081141562000b8a5762000b8962000bc6565b5b50919050565b62000b9b8262000c38565b810181811067ffffffffffffffff8211171562000bbd5762000bbc62000bf5565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b62000c548162000ace565b811462000c6057600080fd5b50565b6151618062000c736000396000f3fe6080604052600436106103755760003560e01c806370a08231116101d1578063aeea297e11610102578063da3ef23f116100a0578063e985e9c51161006f578063e985e9c514610c1c578063f2fde38b14610c59578063f3597cd414610c82578063f408928d14610cab57610375565b8063da3ef23f14610b71578063dc33e68114610b9a578063df4305d214610bd7578063e3e1e8ef14610c0057610375565b8063c4bf81df116100dc578063c4bf81df14610ab5578063c668286214610ade578063c87b56dd14610b09578063d62280b214610b4657610375565b8063aeea297e14610a36578063b58be57214610a61578063b88d4fde14610a8c57610375565b806393bd67c31161016f578063a035b1fe11610149578063a035b1fe1461098c578063a22cb465146109b7578063a31d99d8146109e0578063a475b5dd14610a0b57610375565b806393bd67c31461091f578063946ef42a1461093657806395d89b411461096157610375565b806388d15d50116101ab57806388d15d501461087757806389b0649b146108a05780638da5cb5b146108b75780639231ab2a146108e257610375565b806370a08231146107f8578063715018a61461083557806386c685b21461084c57610375565b80633100a535116102ab5780635568ea17116102495780636352211e116102235780636352211e1461073a57806366e2bed01461077757806368428a1b146107a25780636c0360eb146107cd57610375565b80635568ea17146106d157806355f804b3146106fa5780635b8ad4291461072357610375565b80633ccfd60b116102855780633ccfd60b1461064857806342842e0e1461065257806350f7c2041461067b57806353135ca0146106a657610375565b80633100a535146105db57806331f9c919146105f257806333fdc4271461061d57610375565b8063095ea7b31161031857806324a29c02116102f257806324a29c021461053057806328574fda146105595780632a85db55146105965780632db11544146105bf57610375565b8063095ea7b3146104b357806318160ddd146104dc57806323b872dd1461050757610375565b80630538022711610354578063053802271461040b57806306c5b1171461042257806306fdde031461044b578063081812fc1461047657610375565b80620e7fa81461037a57806301547486146103a557806301ffc9a7146103ce575b600080fd5b34801561038657600080fd5b5061038f610cd6565b60405161039c9190614875565b60405180910390f35b3480156103b157600080fd5b506103cc60048036038101906103c79190613fcf565b610cdc565b005b3480156103da57600080fd5b506103f560048036038101906103f09190613f2c565b610d62565b60405161040291906145c2565b60405180910390f35b34801561041757600080fd5b50610420610df4565b005b34801561042e57600080fd5b5061044960048036038101906104449190613fcf565b610e8d565b005b34801561045757600080fd5b50610460610f5d565b60405161046d91906145f8565b60405180910390f35b34801561048257600080fd5b5061049d60048036038101906104989190613fcf565b610fef565b6040516104aa919061455b565b60405180910390f35b3480156104bf57600080fd5b506104da60048036038101906104d59190613e72565b61106b565b005b3480156104e857600080fd5b506104f1611212565b6040516104fe9190614875565b60405180910390f35b34801561051357600080fd5b5061052e60048036038101906105299190613d5c565b611229565b005b34801561053c57600080fd5b5061055760048036038101906105529190613fcf565b611239565b005b34801561056557600080fd5b50610580600480360381019061057b9190613cef565b611309565b60405161058d91906145c2565b60405180910390f35b3480156105a257600080fd5b506105bd60048036038101906105b89190613f86565b611329565b005b6105d960048036038101906105d49190613fcf565b6113bf565b005b3480156105e757600080fd5b506105f0611568565b005b3480156105fe57600080fd5b5061060761162b565b60405161061491906145c2565b60405180910390f35b34801561062957600080fd5b5061063261163e565b60405161063f9190614875565b60405180910390f35b610650611644565b005b34801561065e57600080fd5b5061067960048036038101906106749190613d5c565b6117cc565b005b34801561068757600080fd5b506106906117ec565b60405161069d9190614875565b60405180910390f35b3480156106b257600080fd5b506106bb6117f2565b6040516106c891906145c2565b60405180910390f35b3480156106dd57600080fd5b506106f860048036038101906106f39190613eff565b611805565b005b34801561070657600080fd5b50610721600480360381019061071c9190613f86565b61188b565b005b34801561072f57600080fd5b50610738611971565b005b34801561074657600080fd5b50610761600480360381019061075c9190613fcf565b611a19565b60405161076e919061455b565b60405180910390f35b34801561078357600080fd5b5061078c611a2b565b60405161079991906145c2565b60405180910390f35b3480156107ae57600080fd5b506107b7611a3e565b6040516107c491906145c2565b60405180910390f35b3480156107d957600080fd5b506107e2611a51565b6040516107ef91906145f8565b60405180910390f35b34801561080457600080fd5b5061081f600480360381019061081a9190613cef565b611adf565b60405161082c9190614875565b60405180910390f35b34801561084157600080fd5b5061084a611b74565b005b34801561085857600080fd5b50610861611bfc565b60405161086e9190614875565b60405180910390f35b34801561088357600080fd5b5061089e60048036038101906108999190613eb2565b611c02565b005b3480156108ac57600080fd5b506108b5611ec2565b005b3480156108c357600080fd5b506108cc611f6a565b6040516108d9919061455b565b60405180910390f35b3480156108ee57600080fd5b5061090960048036038101906109049190613fcf565b611f94565b604051610916919061485a565b60405180910390f35b34801561092b57600080fd5b50610934611fac565b005b34801561094257600080fd5b5061094b612054565b6040516109589190614875565b60405180910390f35b34801561096d57600080fd5b5061097661205a565b60405161098391906145f8565b60405180910390f35b34801561099857600080fd5b506109a16120ec565b6040516109ae9190614875565b60405180910390f35b3480156109c357600080fd5b506109de60048036038101906109d99190613e32565b6120f2565b005b3480156109ec57600080fd5b506109f561226a565b604051610a029190614875565b60405180910390f35b348015610a1757600080fd5b50610a20612270565b604051610a2d91906145c2565b60405180910390f35b348015610a4257600080fd5b50610a4b612283565b604051610a5891906145dd565b60405180910390f35b348015610a6d57600080fd5b50610a76612289565b604051610a839190614875565b60405180910390f35b348015610a9857600080fd5b50610ab36004803603810190610aae9190613daf565b61228f565b005b348015610ac157600080fd5b50610adc6004803603810190610ad79190613eff565b612302565b005b348015610aea57600080fd5b50610af3612388565b604051610b0091906145f8565b60405180910390f35b348015610b1557600080fd5b50610b306004803603810190610b2b9190613fcf565b612416565b604051610b3d91906145f8565b60405180910390f35b348015610b5257600080fd5b50610b5b61255e565b604051610b6891906145f8565b60405180910390f35b348015610b7d57600080fd5b50610b986004803603810190610b939190613f86565b6125ec565b005b348015610ba657600080fd5b50610bc16004803603810190610bbc9190613cef565b6126d2565b604051610bce9190614875565b60405180910390f35b348015610be357600080fd5b50610bfe6004803603810190610bf99190613fcf565b6126e4565b005b610c1a6004803603810190610c159190613ffc565b61276a565b005b348015610c2857600080fd5b50610c436004803603810190610c3e9190613d1c565b612b00565b604051610c5091906145c2565b60405180910390f35b348015610c6557600080fd5b50610c806004803603810190610c7b9190613cef565b612b66565b005b348015610c8e57600080fd5b50610ca96004803603810190610ca49190613fcf565b612c5e565b005b348015610cb757600080fd5b50610cc0612ce4565b604051610ccd91906145dd565b60405180910390f35b600d5481565b610ce4612d9b565b73ffffffffffffffffffffffffffffffffffffffff16610d02611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614610d58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4f9061477a565b60405180910390fd5b80600e8190555050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610dbd57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610ded5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b610dfc612d9b565b73ffffffffffffffffffffffffffffffffffffffff16610e1a611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614610e70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e679061477a565b60405180910390fd5b6001601760006101000a81548160ff021916908315150217905550565b610e95612d9b565b73ffffffffffffffffffffffffffffffffffffffff16610eb3611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614610f09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f009061477a565b60405180910390fd5b610f11611212565b811015610f53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4a9061465a565b60405180910390fd5b80600a8190555050565b606060028054610f6c90614afe565b80601f0160208091040260200160405190810160405280929190818152602001828054610f9890614afe565b8015610fe55780601f10610fba57610100808354040283529160200191610fe5565b820191906000526020600020905b815481529060010190602001808311610fc857829003601f168201915b5050505050905090565b6000610ffa82612daa565b611030576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061107682612e09565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156110de576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166110fd612ed7565b73ffffffffffffffffffffffffffffffffffffffff16146111605761112981611124612ed7565b612b00565b61115f576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600061121c612edf565b6001546000540303905090565b611234838383612ee8565b505050565b611241612d9b565b73ffffffffffffffffffffffffffffffffffffffff1661125f611f6a565b73ffffffffffffffffffffffffffffffffffffffff16146112b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ac9061477a565b60405180910390fd5b6112bd611212565b8110156112ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112f69061465a565b60405180910390fd5b8060098190555050565b60116020528060005260406000206000915054906101000a900460ff1681565b611331612d9b565b73ffffffffffffffffffffffffffffffffffffffff1661134f611f6a565b73ffffffffffffffffffffffffffffffffffffffff16146113a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139c9061477a565b60405180910390fd5b80601690805190602001906113bb929190613a55565b5050565b601760039054906101000a900460ff1661140e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611405906146fa565b60405180910390fd5b601760019054906101000a900460ff1661145d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114549061483a565b60405180910390fd5b6010548161146a336132b0565b611474919061497a565b11156114b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ac9061471a565b60405180910390fd5b600954816114c1611212565b6114cb919061497a565b111561150c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611503906146da565b60405180910390fd5b80600c5461151a91906149d0565b341461155b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115529061475a565b60405180910390fd5b6115653382613307565b50565b611570612d9b565b73ffffffffffffffffffffffffffffffffffffffff1661158e611f6a565b73ffffffffffffffffffffffffffffffffffffffff16146115e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115db9061477a565b60405180910390fd5b601760019054906101000a900460ff1615601760016101000a81548160ff0219169083151502179055506000601760026101000a81548160ff021916908315150217905550565b601760039054906101000a900460ff1681565b60105481565b61164c612d9b565b73ffffffffffffffffffffffffffffffffffffffff1661166a611f6a565b73ffffffffffffffffffffffffffffffffffffffff16146116c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b79061477a565b60405180910390fd5b600047905060008111611708576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ff9061473a565b60405180910390fd5b600073785c9c71337e5f31ea51135c6f78c436a5bda5c973ffffffffffffffffffffffffffffffffffffffff168260405161174290614546565b60006040518083038185875af1925050503d806000811461177f576040519150601f19603f3d011682016040523d82523d6000602084013e611784565b606091505b50509050806117c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117bf906147da565b60405180910390fd5b5050565b6117e78383836040518060200160405280600081525061228f565b505050565b60095481565b601760029054906101000a900460ff1681565b61180d612d9b565b73ffffffffffffffffffffffffffffffffffffffff1661182b611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614611881576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118789061477a565b60405180910390fd5b8060138190555050565b611893612d9b565b73ffffffffffffffffffffffffffffffffffffffff166118b1611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614611907576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118fe9061477a565b60405180910390fd5b601760009054906101000a900460ff1615611957576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161194e906146ba565b60405180910390fd5b806014908051906020019061196d929190613a55565b5050565b611979612d9b565b73ffffffffffffffffffffffffffffffffffffffff16611997611f6a565b73ffffffffffffffffffffffffffffffffffffffff16146119ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e49061477a565b60405180910390fd5b601760049054906101000a900460ff1615601760046101000a81548160ff021916908315150217905550565b6000611a2482612e09565b9050919050565b601760009054906101000a900460ff1681565b601760019054906101000a900460ff1681565b60148054611a5e90614afe565b80601f0160208091040260200160405190810160405280929190818152602001828054611a8a90614afe565b8015611ad75780601f10611aac57610100808354040283529160200191611ad7565b820191906000526020600020905b815481529060010190602001808311611aba57829003601f168201915b505050505081565b600080611aeb83613325565b1415611b23576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611b7c612d9b565b73ffffffffffffffffffffffffffffffffffffffff16611b9a611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614611bf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be79061477a565b60405180910390fd5b611bfa600061332f565b565b600a5481565b600033604051602001611c1591906144fc565b604051602081830303815290604052805190602001209050601760039054906101000a900460ff16611c7c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c73906146fa565b60405180910390fd5b601760029054906101000a900460ff1615611ccc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc39061467a565b60405180910390fd5b601760019054906101000a900460ff1615611d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d139061467a565b60405180910390fd5b611d6a838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050601254836133f5565b611da9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611da09061481a565b60405180910390fd5b600e546001611db7336132b0565b611dc1919061497a565b1115611e02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611df99061469a565b60405180910390fd5b600a546001611e0f611212565b611e19919061497a565b1115611e5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e51906146da565b60405180910390fd5b6001601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611ebd336001613307565b505050565b611eca612d9b565b73ffffffffffffffffffffffffffffffffffffffff16611ee8611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614611f3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f359061477a565b60405180910390fd5b601760029054906101000a900460ff1615601760026101000a81548160ff021916908315150217905550565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611f9c613adb565b611fa58261340c565b9050919050565b611fb4612d9b565b73ffffffffffffffffffffffffffffffffffffffff16611fd2611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614612028576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161201f9061477a565b60405180910390fd5b601760039054906101000a900460ff1615601760036101000a81548160ff021916908315150217905550565b600f5481565b60606003805461206990614afe565b80601f016020809104026020016040519081016040528092919081815260200182805461209590614afe565b80156120e25780601f106120b7576101008083540402835291602001916120e2565b820191906000526020600020905b8154815290600101906020018083116120c557829003601f168201915b5050505050905090565b600c5481565b6120fa612ed7565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561215f576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806007600061216c612ed7565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612219612ed7565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161225e91906145c2565b60405180910390a35050565b600e5481565b601760049054906101000a900460ff1681565b60135481565b600b5481565b61229a848484612ee8565b60008373ffffffffffffffffffffffffffffffffffffffff163b146122fc576122c58484848461342c565b6122fb576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b61230a612d9b565b73ffffffffffffffffffffffffffffffffffffffff16612328611f6a565b73ffffffffffffffffffffffffffffffffffffffff161461237e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123759061477a565b60405180910390fd5b8060128190555050565b6015805461239590614afe565b80601f01602080910402602001604051908101604052809291908181526020018280546123c190614afe565b801561240e5780601f106123e35761010080835404028352916020019161240e565b820191906000526020600020905b8154815290600101906020018083116123f157829003601f168201915b505050505081565b606061242182612daa565b612457576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601760049054906101000a900460ff16156124cb5760006014805461247b90614afe565b9050141561249857604051806020016040528060008152506124c4565b60146124a38361358c565b6040516020016124b4929190614517565b6040516020818303038152906040525b9050612559565b601680546124d890614afe565b80601f016020809104026020016040519081016040528092919081815260200182805461250490614afe565b80156125515780601f1061252657610100808354040283529160200191612551565b820191906000526020600020905b81548152906001019060200180831161253457829003601f168201915b505050505090505b919050565b6016805461256b90614afe565b80601f016020809104026020016040519081016040528092919081815260200182805461259790614afe565b80156125e45780601f106125b9576101008083540402835291602001916125e4565b820191906000526020600020905b8154815290600101906020018083116125c757829003601f168201915b505050505081565b6125f4612d9b565b73ffffffffffffffffffffffffffffffffffffffff16612612611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614612668576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265f9061477a565b60405180910390fd5b601760009054906101000a900460ff16156126b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126af906146ba565b60405180910390fd5b80601590805190602001906126ce929190613a55565b5050565b60006126dd826132b0565b9050919050565b6126ec612d9b565b73ffffffffffffffffffffffffffffffffffffffff1661270a611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614612760576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127579061477a565b60405180910390fd5b80600f8190555050565b60003360405160200161277d91906144fc565b604051602081830303815290604052805190602001209050601760039054906101000a900460ff166127e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127db906146fa565b60405180910390fd5b601760029054906101000a900460ff16612833576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161282a9061461a565b60405180910390fd5b601760019054906101000a900460ff1615612883576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161287a906147fa565b60405180910390fd5b601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612910576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612907906147ba565b60405180910390fd5b61295e838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050601354836133f5565b806129b357506129b2838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050601254836133f5565b5b6129f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129e99061481a565b60405180910390fd5b600f54846129ff336132b0565b612a09919061497a565b1115612a4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a419061479a565b60405180910390fd5b60095484612a56611212565b612a60919061497a565b1115612aa1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a98906146da565b60405180910390fd5b83600d54612aaf91906149d0565b3414612af0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae79061475a565b60405180910390fd5b612afa3385613307565b50505050565b60007358807bad0b376efc12f5ad86aac70e78ed67deae73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612b535760019050612b60565b612b5d83836135e6565b90505b92915050565b612b6e612d9b565b73ffffffffffffffffffffffffffffffffffffffff16612b8c611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614612be2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bd99061477a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612c52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c499061463a565b60405180910390fd5b612c5b8161332f565b50565b612c66612d9b565b73ffffffffffffffffffffffffffffffffffffffff16612c84611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614612cda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cd19061477a565b60405180910390fd5b8060108190555050565b60125481565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415612d9457600080368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050600080369050905073ffffffffffffffffffffffffffffffffffffffff818301511692505050612d98565b3390505b90565b6000612da5612cea565b905090565b600081612db5612edf565b11158015612dc4575060005482105b8015612e02575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60008082905080612e18612edf565b11612ea057600054811015612e9f5760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082161415612e9d575b6000811415612e93576004600083600190039350838152602001908152602001600020549050612e68565b8092505050612ed2565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b60006001905090565b6000612ef382612e09565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612f5a576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006006600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008573ffffffffffffffffffffffffffffffffffffffff16612fb3612ed7565b73ffffffffffffffffffffffffffffffffffffffff161480612fe25750612fe186612fdc612ed7565b612b00565b5b8061301f5750612ff0612ed7565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b905080613058576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061306386613325565b141561309b576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130a8868686600161367a565b60006130b383613325565b146130ef576006600085815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b6131b687613325565b1717600460008681526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008416141561324057600060018501905060006004600083815260200190815260200160002054141561323e57600054811461323d578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46132a88686866001613680565b505050505050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b613321828260405180602001604052806000815250613686565b5050565b6000819050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000826134028584613917565b1490509392505050565b613414613adb565b61342561342083612e09565b61396d565b9050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613452612ed7565b8786866040518563ffffffff1660e01b81526004016134749493929190614576565b602060405180830381600087803b15801561348e57600080fd5b505af19250505080156134bf57506040513d601f19601f820116820180604052508101906134bc9190613f59565b60015b613539573d80600081146134ef576040519150601f19603f3d011682016040523d82523d6000602084013e6134f4565b606091505b50600081511415613531576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606080604051019050806040528082600183039250600a81066030018353600a810490505b80156135d257600183039250600a81066030018353600a810490506135b2565b508181036020830392508083525050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b50505050565b50505050565b600080549050600061369785613325565b14156136cf576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083141561370a576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613717600085838661367a565b600160406001901b178302600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e161377c60018514613a09565b901b60a042901b61378c86613325565b1717600460008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b14613890575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4613840600087848060010195508761342c565b613876576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082106137d157826000541461388b57600080fd5b6138fb565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808210613891575b8160008190555050506139116000858386613680565b50505050565b60008082905060005b84518110156139625761394d828683815181106139405761393f614c2c565b5b6020026020010151613a13565b9150808061395a90614b61565b915050613920565b508091505092915050565b613975613adb565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c010000000000000000000000000000000000000000000000000000000083161415816040019015159081151581525050919050565b6000819050919050565b6000818310613a2b57613a268284613a3e565b613a36565b613a358383613a3e565b5b905092915050565b600082600052816020526040600020905092915050565b828054613a6190614afe565b90600052602060002090601f016020900481019282613a835760008555613aca565b82601f10613a9c57805160ff1916838001178555613aca565b82800160010185558215613aca579182015b82811115613ac9578251825591602001919060010190613aae565b5b509050613ad79190613b1e565b5090565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b5b80821115613b37576000816000905550600101613b1f565b5090565b6000613b4e613b49846148b5565b614890565b905082815260208101848484011115613b6a57613b69614c99565b5b613b75848285614abc565b509392505050565b6000613b90613b8b846148e6565b614890565b905082815260208101848484011115613bac57613bab614c99565b5b613bb7848285614abc565b509392505050565b600081359050613bce816150b8565b92915050565b60008083601f840112613bea57613be9614c8f565b5b8235905067ffffffffffffffff811115613c0757613c06614c8a565b5b602083019150836020820283011115613c2357613c22614c94565b5b9250929050565b600081359050613c39816150cf565b92915050565b600081359050613c4e816150e6565b92915050565b600081359050613c63816150fd565b92915050565b600081519050613c78816150fd565b92915050565b600082601f830112613c9357613c92614c8f565b5b8135613ca3848260208601613b3b565b91505092915050565b600082601f830112613cc157613cc0614c8f565b5b8135613cd1848260208601613b7d565b91505092915050565b600081359050613ce981615114565b92915050565b600060208284031215613d0557613d04614ca3565b5b6000613d1384828501613bbf565b91505092915050565b60008060408385031215613d3357613d32614ca3565b5b6000613d4185828601613bbf565b9250506020613d5285828601613bbf565b9150509250929050565b600080600060608486031215613d7557613d74614ca3565b5b6000613d8386828701613bbf565b9350506020613d9486828701613bbf565b9250506040613da586828701613cda565b9150509250925092565b60008060008060808587031215613dc957613dc8614ca3565b5b6000613dd787828801613bbf565b9450506020613de887828801613bbf565b9350506040613df987828801613cda565b925050606085013567ffffffffffffffff811115613e1a57613e19614c9e565b5b613e2687828801613c7e565b91505092959194509250565b60008060408385031215613e4957613e48614ca3565b5b6000613e5785828601613bbf565b9250506020613e6885828601613c2a565b9150509250929050565b60008060408385031215613e8957613e88614ca3565b5b6000613e9785828601613bbf565b9250506020613ea885828601613cda565b9150509250929050565b60008060208385031215613ec957613ec8614ca3565b5b600083013567ffffffffffffffff811115613ee757613ee6614c9e565b5b613ef385828601613bd4565b92509250509250929050565b600060208284031215613f1557613f14614ca3565b5b6000613f2384828501613c3f565b91505092915050565b600060208284031215613f4257613f41614ca3565b5b6000613f5084828501613c54565b91505092915050565b600060208284031215613f6f57613f6e614ca3565b5b6000613f7d84828501613c69565b91505092915050565b600060208284031215613f9c57613f9b614ca3565b5b600082013567ffffffffffffffff811115613fba57613fb9614c9e565b5b613fc684828501613cac565b91505092915050565b600060208284031215613fe557613fe4614ca3565b5b6000613ff384828501613cda565b91505092915050565b60008060006040848603121561401557614014614ca3565b5b600061402386828701613cda565b935050602084013567ffffffffffffffff81111561404457614043614c9e565b5b61405086828701613bd4565b92509250509250925092565b61406581614a2a565b82525050565b61407481614a2a565b82525050565b61408b61408682614a2a565b614baa565b82525050565b61409a81614a3c565b82525050565b6140a981614a3c565b82525050565b6140b881614a48565b82525050565b60006140c98261492c565b6140d38185614942565b93506140e3818560208601614acb565b6140ec81614ca8565b840191505092915050565b600061410282614937565b61410c818561495e565b935061411c818560208601614acb565b61412581614ca8565b840191505092915050565b600061413b82614937565b614145818561496f565b9350614155818560208601614acb565b80840191505092915050565b6000815461416e81614afe565b614178818661496f565b9450600182166000811461419357600181146141a4576141d7565b60ff198316865281860193506141d7565b6141ad85614917565b60005b838110156141cf578154818901526001820191506020810190506141b0565b838801955050505b50505092915050565b60006141ed601a8361495e565b91506141f882614cc6565b602082019050919050565b600061421060268361495e565b915061421b82614cef565b604082019050919050565b6000614233602e8361495e565b915061423e82614d3e565b604082019050919050565b600061425660138361495e565b915061426182614d8d565b602082019050919050565b600061427960178361495e565b915061428482614db6565b602082019050919050565b600061429c600d8361495e565b91506142a782614ddf565b602082019050919050565b60006142bf601b8361495e565b91506142ca82614e08565b602082019050919050565b60006142e2601a8361495e565b91506142ed82614e31565b602082019050919050565b6000614305602b8361495e565b915061431082614e5a565b604082019050919050565b600061432860138361495e565b915061433382614ea9565b602082019050919050565b600061434b60308361495e565b915061435682614ed2565b604082019050919050565b600061436e60058361496f565b915061437982614f21565b600582019050919050565b600061439160208361495e565b915061439c82614f4a565b602082019050919050565b60006143b460278361495e565b91506143bf82614f73565b604082019050919050565b60006143d7603f8361495e565b91506143e282614fc2565b604082019050919050565b60006143fa60188361495e565b915061440582615011565b602082019050919050565b600061441d60128361495e565b91506144288261503a565b602082019050919050565b600061444060188361495e565b915061444b82615063565b602082019050919050565b6000614463600083614953565b915061446e8261508c565b600082019050919050565b600061448660208361495e565b91506144918261508f565b602082019050919050565b6060820160008201516144b2600085018261405c565b5060208201516144c560208501826144ed565b5060408201516144d86040850182614091565b50505050565b6144e781614a9e565b82525050565b6144f681614aa8565b82525050565b6000614508828461407a565b60148201915081905092915050565b60006145238285614161565b915061452f8284614130565b915061453a82614361565b91508190509392505050565b600061455182614456565b9150819050919050565b6000602082019050614570600083018461406b565b92915050565b600060808201905061458b600083018761406b565b614598602083018661406b565b6145a560408301856144de565b81810360608301526145b781846140be565b905095945050505050565b60006020820190506145d760008301846140a0565b92915050565b60006020820190506145f260008301846140af565b92915050565b6000602082019050818103600083015261461281846140f7565b905092915050565b60006020820190508181036000830152614633816141e0565b9050919050565b6000602082019050818103600083015261465381614203565b9050919050565b6000602082019050818103600083015261467381614226565b9050919050565b6000602082019050818103600083015261469381614249565b9050919050565b600060208201905081810360008301526146b38161426c565b9050919050565b600060208201905081810360008301526146d38161428f565b9050919050565b600060208201905081810360008301526146f3816142b2565b9050919050565b60006020820190508181036000830152614713816142d5565b9050919050565b60006020820190508181036000830152614733816142f8565b9050919050565b600060208201905081810360008301526147538161431b565b9050919050565b600060208201905081810360008301526147738161433e565b9050919050565b6000602082019050818103600083015261479381614384565b9050919050565b600060208201905081810360008301526147b3816143a7565b9050919050565b600060208201905081810360008301526147d3816143ca565b9050919050565b600060208201905081810360008301526147f3816143ed565b9050919050565b6000602082019050818103600083015261481381614410565b9050919050565b6000602082019050818103600083015261483381614433565b9050919050565b6000602082019050818103600083015261485381614479565b9050919050565b600060608201905061486f600083018461449c565b92915050565b600060208201905061488a60008301846144de565b92915050565b600061489a6148ab565b90506148a68282614b30565b919050565b6000604051905090565b600067ffffffffffffffff8211156148d0576148cf614c5b565b5b6148d982614ca8565b9050602081019050919050565b600067ffffffffffffffff82111561490157614900614c5b565b5b61490a82614ca8565b9050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600061498582614a9e565b915061499083614a9e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156149c5576149c4614bce565b5b828201905092915050565b60006149db82614a9e565b91506149e683614a9e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614a1f57614a1e614bce565b5b828202905092915050565b6000614a3582614a7e565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600067ffffffffffffffff82169050919050565b82818337600083830152505050565b60005b83811015614ae9578082015181840152602081019050614ace565b83811115614af8576000848401525b50505050565b60006002820490506001821680614b1657607f821691505b60208210811415614b2a57614b29614bfd565b5b50919050565b614b3982614ca8565b810181811067ffffffffffffffff82111715614b5857614b57614c5b565b5b80604052505050565b6000614b6c82614a9e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614b9f57614b9e614bce565b5b600182019050919050565b6000614bb582614bbc565b9050919050565b6000614bc782614cb9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f50726573616c65206973206e6f7420616374697665207965742e000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4e657720737570706c792063616e6e6f74206265206c6f776572207468616e2060008201527f63757272656e7420737570706c79000000000000000000000000000000000000602082015250565b7f46726565206d696e7420697320636c6f73656400000000000000000000000000600082015250565b7f43616e6e6f74206d696e74206d6f726520746f6b656e73000000000000000000600082015250565b7f555249206973206c6f636b656400000000000000000000000000000000000000600082015250565b7f50726573616c6520737570706c792069732066696e69736865642e0000000000600082015250565b7f4d696e74696e67206973206e6f7420616374697665207965742e000000000000600082015250565b7f43616e6e6f74206d696e74206d6f726520746f6b656e7320647572696e67207060008201527f75626c69632073616c652e000000000000000000000000000000000000000000602082015250565b7f42616c616e6365206d757374206265203e203000000000000000000000000000600082015250565b7f4e6f7420656e6f7567682066756e647320666f7220726571756573746564206e60008201527f756d626572206f6620746f6b656e732e00000000000000000000000000000000602082015250565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f43616e6e6f74206d696e74206d6f726520746f6b656e7320647572696e67207060008201527f726573616c652e00000000000000000000000000000000000000000000000000602082015250565b7f43616e6e6f74206d696e74203a20796f752068617665206d696e74656420612060008201527f4e465420647572696e67207468652066726565206d696e742070686173652e00602082015250565b7f4661696c656420746f2077697468647261772045746865720000000000000000600082015250565b7f50726573616c6520697320636c6f7365642e0000000000000000000000000000600082015250565b7f596f7520617265206e6f742077686974656c69737465642e0000000000000000600082015250565b50565b7f5075626c69632073616c6520686173206e6f742073746172746564207965742e600082015250565b6150c181614a2a565b81146150cc57600080fd5b50565b6150d881614a3c565b81146150e357600080fd5b50565b6150ef81614a48565b81146150fa57600080fd5b50565b61510681614a52565b811461511157600080fd5b50565b61511d81614a9e565b811461512857600080fd5b5056fea2646970667358221220f0cd951a20df80202a955c8e0e198d89704487c301ca3f126dc6554062ff193464736f6c6343000807003300000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106103755760003560e01c806370a08231116101d1578063aeea297e11610102578063da3ef23f116100a0578063e985e9c51161006f578063e985e9c514610c1c578063f2fde38b14610c59578063f3597cd414610c82578063f408928d14610cab57610375565b8063da3ef23f14610b71578063dc33e68114610b9a578063df4305d214610bd7578063e3e1e8ef14610c0057610375565b8063c4bf81df116100dc578063c4bf81df14610ab5578063c668286214610ade578063c87b56dd14610b09578063d62280b214610b4657610375565b8063aeea297e14610a36578063b58be57214610a61578063b88d4fde14610a8c57610375565b806393bd67c31161016f578063a035b1fe11610149578063a035b1fe1461098c578063a22cb465146109b7578063a31d99d8146109e0578063a475b5dd14610a0b57610375565b806393bd67c31461091f578063946ef42a1461093657806395d89b411461096157610375565b806388d15d50116101ab57806388d15d501461087757806389b0649b146108a05780638da5cb5b146108b75780639231ab2a146108e257610375565b806370a08231146107f8578063715018a61461083557806386c685b21461084c57610375565b80633100a535116102ab5780635568ea17116102495780636352211e116102235780636352211e1461073a57806366e2bed01461077757806368428a1b146107a25780636c0360eb146107cd57610375565b80635568ea17146106d157806355f804b3146106fa5780635b8ad4291461072357610375565b80633ccfd60b116102855780633ccfd60b1461064857806342842e0e1461065257806350f7c2041461067b57806353135ca0146106a657610375565b80633100a535146105db57806331f9c919146105f257806333fdc4271461061d57610375565b8063095ea7b31161031857806324a29c02116102f257806324a29c021461053057806328574fda146105595780632a85db55146105965780632db11544146105bf57610375565b8063095ea7b3146104b357806318160ddd146104dc57806323b872dd1461050757610375565b80630538022711610354578063053802271461040b57806306c5b1171461042257806306fdde031461044b578063081812fc1461047657610375565b80620e7fa81461037a57806301547486146103a557806301ffc9a7146103ce575b600080fd5b34801561038657600080fd5b5061038f610cd6565b60405161039c9190614875565b60405180910390f35b3480156103b157600080fd5b506103cc60048036038101906103c79190613fcf565b610cdc565b005b3480156103da57600080fd5b506103f560048036038101906103f09190613f2c565b610d62565b60405161040291906145c2565b60405180910390f35b34801561041757600080fd5b50610420610df4565b005b34801561042e57600080fd5b5061044960048036038101906104449190613fcf565b610e8d565b005b34801561045757600080fd5b50610460610f5d565b60405161046d91906145f8565b60405180910390f35b34801561048257600080fd5b5061049d60048036038101906104989190613fcf565b610fef565b6040516104aa919061455b565b60405180910390f35b3480156104bf57600080fd5b506104da60048036038101906104d59190613e72565b61106b565b005b3480156104e857600080fd5b506104f1611212565b6040516104fe9190614875565b60405180910390f35b34801561051357600080fd5b5061052e60048036038101906105299190613d5c565b611229565b005b34801561053c57600080fd5b5061055760048036038101906105529190613fcf565b611239565b005b34801561056557600080fd5b50610580600480360381019061057b9190613cef565b611309565b60405161058d91906145c2565b60405180910390f35b3480156105a257600080fd5b506105bd60048036038101906105b89190613f86565b611329565b005b6105d960048036038101906105d49190613fcf565b6113bf565b005b3480156105e757600080fd5b506105f0611568565b005b3480156105fe57600080fd5b5061060761162b565b60405161061491906145c2565b60405180910390f35b34801561062957600080fd5b5061063261163e565b60405161063f9190614875565b60405180910390f35b610650611644565b005b34801561065e57600080fd5b5061067960048036038101906106749190613d5c565b6117cc565b005b34801561068757600080fd5b506106906117ec565b60405161069d9190614875565b60405180910390f35b3480156106b257600080fd5b506106bb6117f2565b6040516106c891906145c2565b60405180910390f35b3480156106dd57600080fd5b506106f860048036038101906106f39190613eff565b611805565b005b34801561070657600080fd5b50610721600480360381019061071c9190613f86565b61188b565b005b34801561072f57600080fd5b50610738611971565b005b34801561074657600080fd5b50610761600480360381019061075c9190613fcf565b611a19565b60405161076e919061455b565b60405180910390f35b34801561078357600080fd5b5061078c611a2b565b60405161079991906145c2565b60405180910390f35b3480156107ae57600080fd5b506107b7611a3e565b6040516107c491906145c2565b60405180910390f35b3480156107d957600080fd5b506107e2611a51565b6040516107ef91906145f8565b60405180910390f35b34801561080457600080fd5b5061081f600480360381019061081a9190613cef565b611adf565b60405161082c9190614875565b60405180910390f35b34801561084157600080fd5b5061084a611b74565b005b34801561085857600080fd5b50610861611bfc565b60405161086e9190614875565b60405180910390f35b34801561088357600080fd5b5061089e60048036038101906108999190613eb2565b611c02565b005b3480156108ac57600080fd5b506108b5611ec2565b005b3480156108c357600080fd5b506108cc611f6a565b6040516108d9919061455b565b60405180910390f35b3480156108ee57600080fd5b5061090960048036038101906109049190613fcf565b611f94565b604051610916919061485a565b60405180910390f35b34801561092b57600080fd5b50610934611fac565b005b34801561094257600080fd5b5061094b612054565b6040516109589190614875565b60405180910390f35b34801561096d57600080fd5b5061097661205a565b60405161098391906145f8565b60405180910390f35b34801561099857600080fd5b506109a16120ec565b6040516109ae9190614875565b60405180910390f35b3480156109c357600080fd5b506109de60048036038101906109d99190613e32565b6120f2565b005b3480156109ec57600080fd5b506109f561226a565b604051610a029190614875565b60405180910390f35b348015610a1757600080fd5b50610a20612270565b604051610a2d91906145c2565b60405180910390f35b348015610a4257600080fd5b50610a4b612283565b604051610a5891906145dd565b60405180910390f35b348015610a6d57600080fd5b50610a76612289565b604051610a839190614875565b60405180910390f35b348015610a9857600080fd5b50610ab36004803603810190610aae9190613daf565b61228f565b005b348015610ac157600080fd5b50610adc6004803603810190610ad79190613eff565b612302565b005b348015610aea57600080fd5b50610af3612388565b604051610b0091906145f8565b60405180910390f35b348015610b1557600080fd5b50610b306004803603810190610b2b9190613fcf565b612416565b604051610b3d91906145f8565b60405180910390f35b348015610b5257600080fd5b50610b5b61255e565b604051610b6891906145f8565b60405180910390f35b348015610b7d57600080fd5b50610b986004803603810190610b939190613f86565b6125ec565b005b348015610ba657600080fd5b50610bc16004803603810190610bbc9190613cef565b6126d2565b604051610bce9190614875565b60405180910390f35b348015610be357600080fd5b50610bfe6004803603810190610bf99190613fcf565b6126e4565b005b610c1a6004803603810190610c159190613ffc565b61276a565b005b348015610c2857600080fd5b50610c436004803603810190610c3e9190613d1c565b612b00565b604051610c5091906145c2565b60405180910390f35b348015610c6557600080fd5b50610c806004803603810190610c7b9190613cef565b612b66565b005b348015610c8e57600080fd5b50610ca96004803603810190610ca49190613fcf565b612c5e565b005b348015610cb757600080fd5b50610cc0612ce4565b604051610ccd91906145dd565b60405180910390f35b600d5481565b610ce4612d9b565b73ffffffffffffffffffffffffffffffffffffffff16610d02611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614610d58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4f9061477a565b60405180910390fd5b80600e8190555050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610dbd57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610ded5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b610dfc612d9b565b73ffffffffffffffffffffffffffffffffffffffff16610e1a611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614610e70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e679061477a565b60405180910390fd5b6001601760006101000a81548160ff021916908315150217905550565b610e95612d9b565b73ffffffffffffffffffffffffffffffffffffffff16610eb3611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614610f09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f009061477a565b60405180910390fd5b610f11611212565b811015610f53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4a9061465a565b60405180910390fd5b80600a8190555050565b606060028054610f6c90614afe565b80601f0160208091040260200160405190810160405280929190818152602001828054610f9890614afe565b8015610fe55780601f10610fba57610100808354040283529160200191610fe5565b820191906000526020600020905b815481529060010190602001808311610fc857829003601f168201915b5050505050905090565b6000610ffa82612daa565b611030576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061107682612e09565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156110de576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166110fd612ed7565b73ffffffffffffffffffffffffffffffffffffffff16146111605761112981611124612ed7565b612b00565b61115f576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600061121c612edf565b6001546000540303905090565b611234838383612ee8565b505050565b611241612d9b565b73ffffffffffffffffffffffffffffffffffffffff1661125f611f6a565b73ffffffffffffffffffffffffffffffffffffffff16146112b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ac9061477a565b60405180910390fd5b6112bd611212565b8110156112ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112f69061465a565b60405180910390fd5b8060098190555050565b60116020528060005260406000206000915054906101000a900460ff1681565b611331612d9b565b73ffffffffffffffffffffffffffffffffffffffff1661134f611f6a565b73ffffffffffffffffffffffffffffffffffffffff16146113a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139c9061477a565b60405180910390fd5b80601690805190602001906113bb929190613a55565b5050565b601760039054906101000a900460ff1661140e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611405906146fa565b60405180910390fd5b601760019054906101000a900460ff1661145d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114549061483a565b60405180910390fd5b6010548161146a336132b0565b611474919061497a565b11156114b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ac9061471a565b60405180910390fd5b600954816114c1611212565b6114cb919061497a565b111561150c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611503906146da565b60405180910390fd5b80600c5461151a91906149d0565b341461155b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115529061475a565b60405180910390fd5b6115653382613307565b50565b611570612d9b565b73ffffffffffffffffffffffffffffffffffffffff1661158e611f6a565b73ffffffffffffffffffffffffffffffffffffffff16146115e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115db9061477a565b60405180910390fd5b601760019054906101000a900460ff1615601760016101000a81548160ff0219169083151502179055506000601760026101000a81548160ff021916908315150217905550565b601760039054906101000a900460ff1681565b60105481565b61164c612d9b565b73ffffffffffffffffffffffffffffffffffffffff1661166a611f6a565b73ffffffffffffffffffffffffffffffffffffffff16146116c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b79061477a565b60405180910390fd5b600047905060008111611708576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ff9061473a565b60405180910390fd5b600073785c9c71337e5f31ea51135c6f78c436a5bda5c973ffffffffffffffffffffffffffffffffffffffff168260405161174290614546565b60006040518083038185875af1925050503d806000811461177f576040519150601f19603f3d011682016040523d82523d6000602084013e611784565b606091505b50509050806117c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117bf906147da565b60405180910390fd5b5050565b6117e78383836040518060200160405280600081525061228f565b505050565b60095481565b601760029054906101000a900460ff1681565b61180d612d9b565b73ffffffffffffffffffffffffffffffffffffffff1661182b611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614611881576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118789061477a565b60405180910390fd5b8060138190555050565b611893612d9b565b73ffffffffffffffffffffffffffffffffffffffff166118b1611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614611907576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118fe9061477a565b60405180910390fd5b601760009054906101000a900460ff1615611957576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161194e906146ba565b60405180910390fd5b806014908051906020019061196d929190613a55565b5050565b611979612d9b565b73ffffffffffffffffffffffffffffffffffffffff16611997611f6a565b73ffffffffffffffffffffffffffffffffffffffff16146119ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e49061477a565b60405180910390fd5b601760049054906101000a900460ff1615601760046101000a81548160ff021916908315150217905550565b6000611a2482612e09565b9050919050565b601760009054906101000a900460ff1681565b601760019054906101000a900460ff1681565b60148054611a5e90614afe565b80601f0160208091040260200160405190810160405280929190818152602001828054611a8a90614afe565b8015611ad75780601f10611aac57610100808354040283529160200191611ad7565b820191906000526020600020905b815481529060010190602001808311611aba57829003601f168201915b505050505081565b600080611aeb83613325565b1415611b23576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611b7c612d9b565b73ffffffffffffffffffffffffffffffffffffffff16611b9a611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614611bf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611be79061477a565b60405180910390fd5b611bfa600061332f565b565b600a5481565b600033604051602001611c1591906144fc565b604051602081830303815290604052805190602001209050601760039054906101000a900460ff16611c7c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c73906146fa565b60405180910390fd5b601760029054906101000a900460ff1615611ccc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc39061467a565b60405180910390fd5b601760019054906101000a900460ff1615611d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d139061467a565b60405180910390fd5b611d6a838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050601254836133f5565b611da9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611da09061481a565b60405180910390fd5b600e546001611db7336132b0565b611dc1919061497a565b1115611e02576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611df99061469a565b60405180910390fd5b600a546001611e0f611212565b611e19919061497a565b1115611e5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e51906146da565b60405180910390fd5b6001601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611ebd336001613307565b505050565b611eca612d9b565b73ffffffffffffffffffffffffffffffffffffffff16611ee8611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614611f3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f359061477a565b60405180910390fd5b601760029054906101000a900460ff1615601760026101000a81548160ff021916908315150217905550565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611f9c613adb565b611fa58261340c565b9050919050565b611fb4612d9b565b73ffffffffffffffffffffffffffffffffffffffff16611fd2611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614612028576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161201f9061477a565b60405180910390fd5b601760039054906101000a900460ff1615601760036101000a81548160ff021916908315150217905550565b600f5481565b60606003805461206990614afe565b80601f016020809104026020016040519081016040528092919081815260200182805461209590614afe565b80156120e25780601f106120b7576101008083540402835291602001916120e2565b820191906000526020600020905b8154815290600101906020018083116120c557829003601f168201915b5050505050905090565b600c5481565b6120fa612ed7565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561215f576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806007600061216c612ed7565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612219612ed7565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161225e91906145c2565b60405180910390a35050565b600e5481565b601760049054906101000a900460ff1681565b60135481565b600b5481565b61229a848484612ee8565b60008373ffffffffffffffffffffffffffffffffffffffff163b146122fc576122c58484848461342c565b6122fb576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b61230a612d9b565b73ffffffffffffffffffffffffffffffffffffffff16612328611f6a565b73ffffffffffffffffffffffffffffffffffffffff161461237e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123759061477a565b60405180910390fd5b8060128190555050565b6015805461239590614afe565b80601f01602080910402602001604051908101604052809291908181526020018280546123c190614afe565b801561240e5780601f106123e35761010080835404028352916020019161240e565b820191906000526020600020905b8154815290600101906020018083116123f157829003601f168201915b505050505081565b606061242182612daa565b612457576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601760049054906101000a900460ff16156124cb5760006014805461247b90614afe565b9050141561249857604051806020016040528060008152506124c4565b60146124a38361358c565b6040516020016124b4929190614517565b6040516020818303038152906040525b9050612559565b601680546124d890614afe565b80601f016020809104026020016040519081016040528092919081815260200182805461250490614afe565b80156125515780601f1061252657610100808354040283529160200191612551565b820191906000526020600020905b81548152906001019060200180831161253457829003601f168201915b505050505090505b919050565b6016805461256b90614afe565b80601f016020809104026020016040519081016040528092919081815260200182805461259790614afe565b80156125e45780601f106125b9576101008083540402835291602001916125e4565b820191906000526020600020905b8154815290600101906020018083116125c757829003601f168201915b505050505081565b6125f4612d9b565b73ffffffffffffffffffffffffffffffffffffffff16612612611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614612668576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265f9061477a565b60405180910390fd5b601760009054906101000a900460ff16156126b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126af906146ba565b60405180910390fd5b80601590805190602001906126ce929190613a55565b5050565b60006126dd826132b0565b9050919050565b6126ec612d9b565b73ffffffffffffffffffffffffffffffffffffffff1661270a611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614612760576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127579061477a565b60405180910390fd5b80600f8190555050565b60003360405160200161277d91906144fc565b604051602081830303815290604052805190602001209050601760039054906101000a900460ff166127e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127db906146fa565b60405180910390fd5b601760029054906101000a900460ff16612833576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161282a9061461a565b60405180910390fd5b601760019054906101000a900460ff1615612883576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161287a906147fa565b60405180910390fd5b601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612910576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612907906147ba565b60405180910390fd5b61295e838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050601354836133f5565b806129b357506129b2838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050601254836133f5565b5b6129f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129e99061481a565b60405180910390fd5b600f54846129ff336132b0565b612a09919061497a565b1115612a4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a419061479a565b60405180910390fd5b60095484612a56611212565b612a60919061497a565b1115612aa1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a98906146da565b60405180910390fd5b83600d54612aaf91906149d0565b3414612af0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ae79061475a565b60405180910390fd5b612afa3385613307565b50505050565b60007358807bad0b376efc12f5ad86aac70e78ed67deae73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612b535760019050612b60565b612b5d83836135e6565b90505b92915050565b612b6e612d9b565b73ffffffffffffffffffffffffffffffffffffffff16612b8c611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614612be2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bd99061477a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612c52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c499061463a565b60405180910390fd5b612c5b8161332f565b50565b612c66612d9b565b73ffffffffffffffffffffffffffffffffffffffff16612c84611f6a565b73ffffffffffffffffffffffffffffffffffffffff1614612cda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cd19061477a565b60405180910390fd5b8060108190555050565b60125481565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415612d9457600080368080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050600080369050905073ffffffffffffffffffffffffffffffffffffffff818301511692505050612d98565b3390505b90565b6000612da5612cea565b905090565b600081612db5612edf565b11158015612dc4575060005482105b8015612e02575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60008082905080612e18612edf565b11612ea057600054811015612e9f5760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082161415612e9d575b6000811415612e93576004600083600190039350838152602001908152602001600020549050612e68565b8092505050612ed2565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b60006001905090565b6000612ef382612e09565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612f5a576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006006600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008573ffffffffffffffffffffffffffffffffffffffff16612fb3612ed7565b73ffffffffffffffffffffffffffffffffffffffff161480612fe25750612fe186612fdc612ed7565b612b00565b5b8061301f5750612ff0612ed7565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b905080613058576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061306386613325565b141561309b576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130a8868686600161367a565b60006130b383613325565b146130ef576006600085815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b6131b687613325565b1717600460008681526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008416141561324057600060018501905060006004600083815260200190815260200160002054141561323e57600054811461323d578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46132a88686866001613680565b505050505050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b613321828260405180602001604052806000815250613686565b5050565b6000819050919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000826134028584613917565b1490509392505050565b613414613adb565b61342561342083612e09565b61396d565b9050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613452612ed7565b8786866040518563ffffffff1660e01b81526004016134749493929190614576565b602060405180830381600087803b15801561348e57600080fd5b505af19250505080156134bf57506040513d601f19601f820116820180604052508101906134bc9190613f59565b60015b613539573d80600081146134ef576040519150601f19603f3d011682016040523d82523d6000602084013e6134f4565b606091505b50600081511415613531576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606080604051019050806040528082600183039250600a81066030018353600a810490505b80156135d257600183039250600a81066030018353600a810490506135b2565b508181036020830392508083525050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b50505050565b50505050565b600080549050600061369785613325565b14156136cf576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083141561370a576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613717600085838661367a565b600160406001901b178302600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e161377c60018514613a09565b901b60a042901b61378c86613325565b1717600460008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b14613890575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4613840600087848060010195508761342c565b613876576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082106137d157826000541461388b57600080fd5b6138fb565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808210613891575b8160008190555050506139116000858386613680565b50505050565b60008082905060005b84518110156139625761394d828683815181106139405761393f614c2c565b5b6020026020010151613a13565b9150808061395a90614b61565b915050613920565b508091505092915050565b613975613adb565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c010000000000000000000000000000000000000000000000000000000083161415816040019015159081151581525050919050565b6000819050919050565b6000818310613a2b57613a268284613a3e565b613a36565b613a358383613a3e565b5b905092915050565b600082600052816020526040600020905092915050565b828054613a6190614afe565b90600052602060002090601f016020900481019282613a835760008555613aca565b82601f10613a9c57805160ff1916838001178555613aca565b82800160010185558215613aca579182015b82811115613ac9578251825591602001919060010190613aae565b5b509050613ad79190613b1e565b5090565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b5b80821115613b37576000816000905550600101613b1f565b5090565b6000613b4e613b49846148b5565b614890565b905082815260208101848484011115613b6a57613b69614c99565b5b613b75848285614abc565b509392505050565b6000613b90613b8b846148e6565b614890565b905082815260208101848484011115613bac57613bab614c99565b5b613bb7848285614abc565b509392505050565b600081359050613bce816150b8565b92915050565b60008083601f840112613bea57613be9614c8f565b5b8235905067ffffffffffffffff811115613c0757613c06614c8a565b5b602083019150836020820283011115613c2357613c22614c94565b5b9250929050565b600081359050613c39816150cf565b92915050565b600081359050613c4e816150e6565b92915050565b600081359050613c63816150fd565b92915050565b600081519050613c78816150fd565b92915050565b600082601f830112613c9357613c92614c8f565b5b8135613ca3848260208601613b3b565b91505092915050565b600082601f830112613cc157613cc0614c8f565b5b8135613cd1848260208601613b7d565b91505092915050565b600081359050613ce981615114565b92915050565b600060208284031215613d0557613d04614ca3565b5b6000613d1384828501613bbf565b91505092915050565b60008060408385031215613d3357613d32614ca3565b5b6000613d4185828601613bbf565b9250506020613d5285828601613bbf565b9150509250929050565b600080600060608486031215613d7557613d74614ca3565b5b6000613d8386828701613bbf565b9350506020613d9486828701613bbf565b9250506040613da586828701613cda565b9150509250925092565b60008060008060808587031215613dc957613dc8614ca3565b5b6000613dd787828801613bbf565b9450506020613de887828801613bbf565b9350506040613df987828801613cda565b925050606085013567ffffffffffffffff811115613e1a57613e19614c9e565b5b613e2687828801613c7e565b91505092959194509250565b60008060408385031215613e4957613e48614ca3565b5b6000613e5785828601613bbf565b9250506020613e6885828601613c2a565b9150509250929050565b60008060408385031215613e8957613e88614ca3565b5b6000613e9785828601613bbf565b9250506020613ea885828601613cda565b9150509250929050565b60008060208385031215613ec957613ec8614ca3565b5b600083013567ffffffffffffffff811115613ee757613ee6614c9e565b5b613ef385828601613bd4565b92509250509250929050565b600060208284031215613f1557613f14614ca3565b5b6000613f2384828501613c3f565b91505092915050565b600060208284031215613f4257613f41614ca3565b5b6000613f5084828501613c54565b91505092915050565b600060208284031215613f6f57613f6e614ca3565b5b6000613f7d84828501613c69565b91505092915050565b600060208284031215613f9c57613f9b614ca3565b5b600082013567ffffffffffffffff811115613fba57613fb9614c9e565b5b613fc684828501613cac565b91505092915050565b600060208284031215613fe557613fe4614ca3565b5b6000613ff384828501613cda565b91505092915050565b60008060006040848603121561401557614014614ca3565b5b600061402386828701613cda565b935050602084013567ffffffffffffffff81111561404457614043614c9e565b5b61405086828701613bd4565b92509250509250925092565b61406581614a2a565b82525050565b61407481614a2a565b82525050565b61408b61408682614a2a565b614baa565b82525050565b61409a81614a3c565b82525050565b6140a981614a3c565b82525050565b6140b881614a48565b82525050565b60006140c98261492c565b6140d38185614942565b93506140e3818560208601614acb565b6140ec81614ca8565b840191505092915050565b600061410282614937565b61410c818561495e565b935061411c818560208601614acb565b61412581614ca8565b840191505092915050565b600061413b82614937565b614145818561496f565b9350614155818560208601614acb565b80840191505092915050565b6000815461416e81614afe565b614178818661496f565b9450600182166000811461419357600181146141a4576141d7565b60ff198316865281860193506141d7565b6141ad85614917565b60005b838110156141cf578154818901526001820191506020810190506141b0565b838801955050505b50505092915050565b60006141ed601a8361495e565b91506141f882614cc6565b602082019050919050565b600061421060268361495e565b915061421b82614cef565b604082019050919050565b6000614233602e8361495e565b915061423e82614d3e565b604082019050919050565b600061425660138361495e565b915061426182614d8d565b602082019050919050565b600061427960178361495e565b915061428482614db6565b602082019050919050565b600061429c600d8361495e565b91506142a782614ddf565b602082019050919050565b60006142bf601b8361495e565b91506142ca82614e08565b602082019050919050565b60006142e2601a8361495e565b91506142ed82614e31565b602082019050919050565b6000614305602b8361495e565b915061431082614e5a565b604082019050919050565b600061432860138361495e565b915061433382614ea9565b602082019050919050565b600061434b60308361495e565b915061435682614ed2565b604082019050919050565b600061436e60058361496f565b915061437982614f21565b600582019050919050565b600061439160208361495e565b915061439c82614f4a565b602082019050919050565b60006143b460278361495e565b91506143bf82614f73565b604082019050919050565b60006143d7603f8361495e565b91506143e282614fc2565b604082019050919050565b60006143fa60188361495e565b915061440582615011565b602082019050919050565b600061441d60128361495e565b91506144288261503a565b602082019050919050565b600061444060188361495e565b915061444b82615063565b602082019050919050565b6000614463600083614953565b915061446e8261508c565b600082019050919050565b600061448660208361495e565b91506144918261508f565b602082019050919050565b6060820160008201516144b2600085018261405c565b5060208201516144c560208501826144ed565b5060408201516144d86040850182614091565b50505050565b6144e781614a9e565b82525050565b6144f681614aa8565b82525050565b6000614508828461407a565b60148201915081905092915050565b60006145238285614161565b915061452f8284614130565b915061453a82614361565b91508190509392505050565b600061455182614456565b9150819050919050565b6000602082019050614570600083018461406b565b92915050565b600060808201905061458b600083018761406b565b614598602083018661406b565b6145a560408301856144de565b81810360608301526145b781846140be565b905095945050505050565b60006020820190506145d760008301846140a0565b92915050565b60006020820190506145f260008301846140af565b92915050565b6000602082019050818103600083015261461281846140f7565b905092915050565b60006020820190508181036000830152614633816141e0565b9050919050565b6000602082019050818103600083015261465381614203565b9050919050565b6000602082019050818103600083015261467381614226565b9050919050565b6000602082019050818103600083015261469381614249565b9050919050565b600060208201905081810360008301526146b38161426c565b9050919050565b600060208201905081810360008301526146d38161428f565b9050919050565b600060208201905081810360008301526146f3816142b2565b9050919050565b60006020820190508181036000830152614713816142d5565b9050919050565b60006020820190508181036000830152614733816142f8565b9050919050565b600060208201905081810360008301526147538161431b565b9050919050565b600060208201905081810360008301526147738161433e565b9050919050565b6000602082019050818103600083015261479381614384565b9050919050565b600060208201905081810360008301526147b3816143a7565b9050919050565b600060208201905081810360008301526147d3816143ca565b9050919050565b600060208201905081810360008301526147f3816143ed565b9050919050565b6000602082019050818103600083015261481381614410565b9050919050565b6000602082019050818103600083015261483381614433565b9050919050565b6000602082019050818103600083015261485381614479565b9050919050565b600060608201905061486f600083018461449c565b92915050565b600060208201905061488a60008301846144de565b92915050565b600061489a6148ab565b90506148a68282614b30565b919050565b6000604051905090565b600067ffffffffffffffff8211156148d0576148cf614c5b565b5b6148d982614ca8565b9050602081019050919050565b600067ffffffffffffffff82111561490157614900614c5b565b5b61490a82614ca8565b9050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600061498582614a9e565b915061499083614a9e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156149c5576149c4614bce565b5b828201905092915050565b60006149db82614a9e565b91506149e683614a9e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614a1f57614a1e614bce565b5b828202905092915050565b6000614a3582614a7e565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600067ffffffffffffffff82169050919050565b82818337600083830152505050565b60005b83811015614ae9578082015181840152602081019050614ace565b83811115614af8576000848401525b50505050565b60006002820490506001821680614b1657607f821691505b60208210811415614b2a57614b29614bfd565b5b50919050565b614b3982614ca8565b810181811067ffffffffffffffff82111715614b5857614b57614c5b565b5b80604052505050565b6000614b6c82614a9e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614b9f57614b9e614bce565b5b600182019050919050565b6000614bb582614bbc565b9050919050565b6000614bc782614cb9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f50726573616c65206973206e6f7420616374697665207965742e000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4e657720737570706c792063616e6e6f74206265206c6f776572207468616e2060008201527f63757272656e7420737570706c79000000000000000000000000000000000000602082015250565b7f46726565206d696e7420697320636c6f73656400000000000000000000000000600082015250565b7f43616e6e6f74206d696e74206d6f726520746f6b656e73000000000000000000600082015250565b7f555249206973206c6f636b656400000000000000000000000000000000000000600082015250565b7f50726573616c6520737570706c792069732066696e69736865642e0000000000600082015250565b7f4d696e74696e67206973206e6f7420616374697665207965742e000000000000600082015250565b7f43616e6e6f74206d696e74206d6f726520746f6b656e7320647572696e67207060008201527f75626c69632073616c652e000000000000000000000000000000000000000000602082015250565b7f42616c616e6365206d757374206265203e203000000000000000000000000000600082015250565b7f4e6f7420656e6f7567682066756e647320666f7220726571756573746564206e60008201527f756d626572206f6620746f6b656e732e00000000000000000000000000000000602082015250565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f43616e6e6f74206d696e74206d6f726520746f6b656e7320647572696e67207060008201527f726573616c652e00000000000000000000000000000000000000000000000000602082015250565b7f43616e6e6f74206d696e74203a20796f752068617665206d696e74656420612060008201527f4e465420647572696e67207468652066726565206d696e742070686173652e00602082015250565b7f4661696c656420746f2077697468647261772045746865720000000000000000600082015250565b7f50726573616c6520697320636c6f7365642e0000000000000000000000000000600082015250565b7f596f7520617265206e6f742077686974656c69737465642e0000000000000000600082015250565b50565b7f5075626c69632073616c6520686173206e6f742073746172746564207965742e600082015250565b6150c181614a2a565b81146150cc57600080fd5b50565b6150d881614a3c565b81146150e357600080fd5b50565b6150ef81614a48565b81146150fa57600080fd5b50565b61510681614a52565b811461511157600080fd5b50565b61511d81614a9e565b811461512857600080fd5b5056fea2646970667358221220f0cd951a20df80202a955c8e0e198d89704487c301ca3f126dc6554062ff193464736f6c63430008070033

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

00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _initialBaseURI (string):

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

93942:7753:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94338:42;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97663:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;12922:615;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96399:76;;;;;;;;;;;;;:::i;:::-;;97238:210;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;17945:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;20013:204;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19473:474;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;11976:315;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;20899:170;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;97456:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94601:46;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95538:99;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;100057:561;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96896:122;;;;;;;;;;;;;:::i;:::-;;95012:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94538:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100685:318;;;:::i;:::-;;21140:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94067:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94980:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95676:109;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96058:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;95453:77;;;;;;;;;;;;;:::i;:::-;;17734:144;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94924:20;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94951:22;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94823:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;13601:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52301:103;;;;;;;;;;;;;:::i;:::-;;94113:44;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98310:740;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;97026:98;;;;;;;;;;;;;:::i;:::-;;51650:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98134:136;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97132:98;;;;;;;;;;;;;:::i;:::-;;94483:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18114:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94297:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;20289:308;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94440:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95044:18;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94757:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94182:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21396:396;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;95793:118;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94851:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96483:370;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94885:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96217:176;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;98013:113;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97769:99;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;99058:991;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101040:469;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52559:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;97876:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94687:45;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94338:42;;;;:::o;97663:100::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;97751:4:::1;97737:11;:18;;;;97663:100:::0;:::o;12922:615::-;13007:4;13322:10;13307:25;;:11;:25;;;;:102;;;;13399:10;13384:25;;:11;:25;;;;13307:102;:179;;;;13476:10;13461:25;;:11;:25;;;;13307:179;13287:199;;12922:615;;;:::o;96399:76::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96463:4:::1;96452:8;;:15;;;;;;;;;;;;;;;;;;96399:76::o:0;97238:210::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;97333:13:::1;:11;:13::i;:::-;97322:7;:24;;97314:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;97433:7;97408:22;:32;;;;97238:210:::0;:::o;17945:100::-;17999:13;18032:5;18025:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17945:100;:::o;20013:204::-;20081:7;20106:16;20114:7;20106;:16::i;:::-;20101:64;;20131:34;;;;;;;;;;;;;;20101:64;20185:15;:24;20201:7;20185:24;;;;;;;;;;;;;;;;;;;;;20178:31;;20013:204;;;:::o;19473:474::-;19546:13;19578:27;19597:7;19578:18;:27::i;:::-;19546:61;;19628:5;19622:11;;:2;:11;;;19618:48;;;19642:24;;;;;;;;;;;;;;19618:48;19706:5;19683:28;;:19;:17;:19::i;:::-;:28;;;19679:175;;19731:44;19748:5;19755:19;:17;:19::i;:::-;19731:16;:44::i;:::-;19726:128;;19803:35;;;;;;;;;;;;;;19726:128;19679:175;19893:2;19866:15;:24;19882:7;19866:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;19931:7;19927:2;19911:28;;19920:5;19911:28;;;;;;;;;;;;19535:412;19473:474;;:::o;11976:315::-;12029:7;12257:15;:13;:15::i;:::-;12242:12;;12226:13;;:28;:46;12219:53;;11976:315;:::o;20899:170::-;21033:28;21043:4;21049:2;21053:7;21033:9;:28::i;:::-;20899:170;;;:::o;97456:201::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;97550:13:::1;:11;:13::i;:::-;97539:7;:24;;97531:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;97642:7;97625:14;:24;;;;97456:201:::0;:::o;94601:46::-;;;;;;;;;;;;;;;;;;;;;;:::o;95538:99::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;95626:3:::1;95611:12;:18;;;;;;;;;;;;:::i;:::-;;95538:99:::0;:::o;100057:561::-;100131:13;;;;;;;;;;;100123:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;100194:10;;;;;;;;;;;100186:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;100301:17;;100288:9;100260:25;100274:10;100260:13;:25::i;:::-;:37;;;;:::i;:::-;:58;;100252:114;;;;;;;;;;;;:::i;:::-;;;;;;;;;100414:14;;100401:9;100385:13;:11;:13::i;:::-;:25;;;;:::i;:::-;:43;;100377:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;100499:9;100491:5;;:17;;;;:::i;:::-;100478:9;:30;100470:91;;;;;;;;;;;;:::i;:::-;;;;;;;;;100574:32;100584:10;100596:9;100574;:32::i;:::-;100057:561;:::o;96896:122::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96968:10:::1;;;;;;;;;;;96967:11;96954:10;;:24;;;;;;;;;;;;;;;;;;97005:5;96989:13;;:21;;;;;;;;;;;;;;;;;;96896:122::o:0;95012:25::-;;;;;;;;;;;;;:::o;94538:36::-;;;;:::o;100685:318::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;100743:15:::1;100761:21;100743:39;;100811:1;100801:7;:11;100793:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;100848:12;100873:42;100865:56;;100928:7;100865:75;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;100847:93;;;100959:7;100951:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;100732:271;;100685:318::o:0;21140:185::-;21278:39;21295:4;21301:2;21305:7;21278:39;;;;;;;;;;;;:16;:39::i;:::-;21140:185;;;:::o;94067:36::-;;;;:::o;94980:25::-;;;;;;;;;;;;;:::o;95676:109::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;95766:11:::1;95751:12;:26;;;;95676:109:::0;:::o;96058:152::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96144:8:::1;;;;;;;;;;;96143:9;96135:35;;;;;;;;;;;;:::i;:::-;;;;;;;;;96191:11;96181:7;:21;;;;;;;;;;;;:::i;:::-;;96058:152:::0;:::o;95453:77::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;95516:6:::1;;;;;;;;;;;95515:7;95506:6;;:16;;;;;;;;;;;;;;;;;;95453:77::o:0;17734:144::-;17798:7;17841:27;17860:7;17841:18;:27::i;:::-;17818:52;;17734:144;;;:::o;94924:20::-;;;;;;;;;;;;;:::o;94951:22::-;;;;;;;;;;;;;:::o;94823:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;13601:234::-;13665:7;13717:1;13689:24;13707:5;13689:17;:24::i;:::-;:29;13685:70;;;13727:28;;;;;;;;;;;;;;13685:70;8946:13;13773:18;:25;13792:5;13773:25;;;;;;;;;;;;;;;;:54;13766:61;;13601:234;;;:::o;52301:103::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;52366:30:::1;52393:1;52366:18;:30::i;:::-;52301:103::o:0;94113:44::-;;;;:::o;98310:740::-;98380:12;98422:10;98405:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;98395:39;;;;;;98380:54;;98463:13;;;;;;;;;;;98455:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;98527:13;;;;;;;;;;;98526:14;98518:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;98584:10;;;;;;;;;;;98583:11;98575:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;98637:55;98656:12;;98637:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98669:17;;98687:4;98637:18;:55::i;:::-;98629:92;;;;;;;;;;;;:::i;:::-;;;;;;;;;98772:11;;98767:1;98740:25;98754:10;98740:13;:25::i;:::-;:28;;;;:::i;:::-;:43;;98732:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;98851:22;;98846:1;98830:13;:11;:13::i;:::-;:17;;;;:::i;:::-;:43;;98822:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;98948:4;98917:16;:28;98934:10;98917:28;;;;;;;;;;;;;;;;:35;;;;;;;;;;;;;;;;;;99015:23;99025:10;99036:1;99015:9;:23::i;:::-;98369:681;98310:740;;:::o;97026:98::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;97103:13:::1;;;;;;;;;;;97102:14;97086:13;;:30;;;;;;;;;;;;;;;;;;97026:98::o:0;51650:87::-;51696:7;51723:6;;;;;;;;;;;51716:13;;51650:87;:::o;98134:136::-;98200:21;;:::i;:::-;98241;98254:7;98241:12;:21::i;:::-;98234:28;;98134:136;;;:::o;97132:98::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;97209:13:::1;;;;;;;;;;;97208:14;97192:13;;:30;;;;;;;;;;;;;;;;;;97132:98::o:0;94483:33::-;;;;:::o;18114:104::-;18170:13;18203:7;18196:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18114:104;:::o;94297:34::-;;;;:::o;20289:308::-;20400:19;:17;:19::i;:::-;20388:31;;:8;:31;;;20384:61;;;20428:17;;;;;;;;;;;;;;20384:61;20510:8;20458:18;:39;20477:19;:17;:19::i;:::-;20458:39;;;;;;;;;;;;;;;:49;20498:8;20458:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;20570:8;20534:55;;20549:19;:17;:19::i;:::-;20534:55;;;20580:8;20534:55;;;;;;:::i;:::-;;;;;;;;20289:308;;:::o;94440:30::-;;;;:::o;95044:18::-;;;;;;;;;;;;;:::o;94757:40::-;;;;:::o;94182:33::-;;;;:::o;21396:396::-;21563:28;21573:4;21579:2;21583:7;21563:9;:28::i;:::-;21624:1;21606:2;:14;;;:19;21602:183;;21645:56;21676:4;21682:2;21686:7;21695:5;21645:30;:56::i;:::-;21640:145;;21729:40;;;;;;;;;;;;;;21640:145;21602:183;21396:396;;;;:::o;95793:118::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;95892:11:::1;95872:17;:31;;;;95793:118:::0;:::o;94851:27::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;96483:370::-;96556:13;96587:16;96595:7;96587;:16::i;:::-;96582:59;;96612:29;;;;;;;;;;;;;;96582:59;96659:6;;;;;;;;;;;96656:190;;;96713:1;96694:7;96688:21;;;;;:::i;:::-;;;:26;;:96;;;;;;;;;;;;;;;;;96741:7;96750:18;96760:7;96750:9;:18::i;:::-;96724:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;96688:96;96681:103;;;;96656:190;96822:12;96815:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96483:370;;;;:::o;94885:26::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;96217:176::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96315:8:::1;;;;;;;;;;;96314:9;96306:35;;;;;;;;;;;;:::i;:::-;;;;;;;;;96368:17;96352:13;:33;;;;;;;;;;;;:::i;:::-;;96217:176:::0;:::o;98013:113::-;98071:7;98098:20;98112:5;98098:13;:20::i;:::-;98091:27;;98013:113;;;:::o;97769:99::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;97856:4:::1;97839:14;:21;;;;97769:99:::0;:::o;99058:991::-;99158:12;99200:10;99183:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;99173:39;;;;;;99158:54;;99241:13;;;;;;;;;;;99233:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;99304:13;;;;;;;;;;;99296:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;99368:10;;;;;;;;;;;99367:11;99359:42;;;;;;;;;;;;:::i;:::-;;;;;;;;;99421:16;:28;99438:10;99421:28;;;;;;;;;;;;;;;;;;;;;;;;;99420:29;99412:105;;;;;;;;;;;;:::i;:::-;;;;;;;;;99536:50;99555:12;;99536:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99568:12;;99581:4;99536:18;:50::i;:::-;:109;;;;99590:55;99609:12;;99590:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99622:17;;99640:4;99590:18;:55::i;:::-;99536:109;99528:146;;;;;;;;;;;;:::i;:::-;;;;;;;;;99734:14;;99721:9;99693:25;99707:10;99693:13;:25::i;:::-;:37;;;;:::i;:::-;:55;;99685:107;;;;;;;;;;;;:::i;:::-;;;;;;;;;99840:14;;99827:9;99811:13;:11;:13::i;:::-;:25;;;;:::i;:::-;:43;;99803:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;99932:9;99917:12;;:24;;;;:::i;:::-;99904:9;:37;99896:98;;;;;;;;;;;;:::i;:::-;;;;;;;;;100007:32;100017:10;100029:9;100007;:32::i;:::-;99147:902;99058:991;;;:::o;101040:469::-;101156:15;101283:42;101262:64;;:9;:64;;;101258:108;;;101350:4;101343:11;;;;101258:108;101458:43;101483:6;101491:9;101458:24;:43::i;:::-;101451:50;;101040:469;;;;;:::o;52559:201::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;52668:1:::1;52648:22;;:8;:22;;;;52640:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;52724:28;52743:8;52724:18;:28::i;:::-;52559:201:::0;:::o;97876:105::-;51881:12;:10;:12::i;:::-;51870:23;;:7;:5;:7::i;:::-;:23;;;51862:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;97969:4:::1;97949:17;:24;;;;97876:105:::0;:::o;94687:45::-;;;;:::o;93283:650::-;93354:22;93420:4;93398:27;;:10;:27;;;93394:508;;;93442:18;93463:8;;93442:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93486:13;93502:8;;:15;;93486:31;;93754:42;93724:5;93717;93713:17;93707:24;93681:134;93671:144;;93541:289;;93394:508;;;93879:10;93862:28;;93394:508;93283:650;:::o;101517:161::-;101607:14;101646:24;:22;:24::i;:::-;101639:31;;101517:161;:::o;22047:273::-;22104:4;22160:7;22141:15;:13;:15::i;:::-;:26;;:66;;;;;22194:13;;22184:7;:23;22141:66;:152;;;;;22292:1;9716:8;22245:17;:26;22263:7;22245:26;;;;;;;;;;;;:43;:48;22141:152;22121:172;;22047:273;;;:::o;15249:1129::-;15316:7;15336:12;15351:7;15336:22;;15419:4;15400:15;:13;:15::i;:::-;:23;15396:915;;15453:13;;15446:4;:20;15442:869;;;15491:14;15508:17;:23;15526:4;15508:23;;;;;;;;;;;;15491:40;;15624:1;9716:8;15597:6;:23;:28;15593:699;;;16116:113;16133:1;16123:6;:11;16116:113;;;16176:17;:25;16194:6;;;;;;;16176:25;;;;;;;;;;;;16167:34;;16116:113;;;16262:6;16255:13;;;;;;15593:699;15468:843;15442:869;15396:915;16339:31;;;;;;;;;;;;;;15249:1129;;;;:::o;36314:105::-;36374:7;36401:10;36394:17;;36314:105;:::o;95313:108::-;95387:7;95412:1;95405:8;;95313:108;:::o;27306:2654::-;27421:27;27451;27470:7;27451:18;:27::i;:::-;27421:57;;27536:4;27495:45;;27511:19;27495:45;;;27491:86;;27549:28;;;;;;;;;;;;;;27491:86;27590:23;27616:15;:24;27632:7;27616:24;;;;;;;;;;;;;;;;;;;;;27590:50;;27653:22;27702:4;27679:27;;:19;:17;:19::i;:::-;:27;;;:87;;;;27723:43;27740:4;27746:19;:17;:19::i;:::-;27723:16;:43::i;:::-;27679:87;:142;;;;27802:19;:17;:19::i;:::-;27783:38;;:15;:38;;;27679:142;27653:169;;27840:17;27835:66;;27866:35;;;;;;;;;;;;;;27835:66;27941:1;27916:21;27934:2;27916:17;:21::i;:::-;:26;27912:62;;;27951:23;;;;;;;;;;;;;;27912:62;27987:43;28009:4;28015:2;28019:7;28028:1;27987:21;:43::i;:::-;28138:1;28100:34;28118:15;28100:17;:34::i;:::-;:39;28096:103;;28163:15;:24;28179:7;28163:24;;;;;;;;;;;;28156:31;;;;;;;;;;;28096:103;28566:18;:24;28585:4;28566:24;;;;;;;;;;;;;;;;28564:26;;;;;;;;;;;;28635:18;:22;28654:2;28635:22;;;;;;;;;;;;;;;;28633:24;;;;;;;;;;;9994:8;9600:3;29016:15;:41;;28974:21;28992:2;28974:17;:21::i;:::-;:84;:128;28928:17;:26;28946:7;28928:26;;;;;;;;;;;:174;;;;29272:1;9994:8;29222:19;:46;:51;29218:626;;;29294:19;29326:1;29316:7;:11;29294:33;;29483:1;29449:17;:30;29467:11;29449:30;;;;;;;;;;;;:35;29445:384;;;29587:13;;29572:11;:28;29568:242;;29767:19;29734:17;:30;29752:11;29734:30;;;;;;;;;;;:52;;;;29568:242;29445:384;29275:569;29218:626;29891:7;29887:2;29872:27;;29881:4;29872:27;;;;;;;;;;;;29910:42;29931:4;29937:2;29941:7;29950:1;29910:20;:42::i;:::-;27410:2550;;;27306:2654;;;:::o;13917:176::-;13978:7;8946:13;9083:2;14006:18;:25;14025:5;14006:25;;;;;;;;;;;;;;;;:49;;14005:80;13998:87;;13917:176;;;:::o;22404:104::-;22473:27;22483:2;22487:8;22473:27;;;;;;;;;;;;:9;:27::i;:::-;22404:104;;:::o;19034:148::-;19098:14;19159:5;19149:15;;19034:148;;;:::o;52920:191::-;52994:16;53013:6;;;;;;;;;;;52994:25;;53039:8;53030:6;;:17;;;;;;;;;;;;;;;;;;53094:8;53063:40;;53084:8;53063:40;;;;;;;;;;;;52983:128;52920:191;:::o;39692:190::-;39817:4;39870;39841:25;39854:5;39861:4;39841:12;:25::i;:::-;:33;39834:40;;39692:190;;;;;:::o;17514:158::-;17576:21;;:::i;:::-;17617:47;17636:27;17655:7;17636:18;:27::i;:::-;17617:18;:47::i;:::-;17610:54;;17514:158;;;:::o;33783:716::-;33946:4;33992:2;33967:45;;;34013:19;:17;:19::i;:::-;34034:4;34040:7;34049:5;33967:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;33963:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34267:1;34250:6;:13;:18;34246:235;;;34296:40;;;;;;;;;;;;;;34246:235;34439:6;34433:13;34424:6;34420:2;34416:15;34409:38;33963:529;34136:54;;;34126:64;;;:6;:64;;;;34119:71;;;33783:716;;;;;;:::o;36525:1943::-;36582:17;37001:3;36994:4;36988:11;36984:21;36977:28;;37092:3;37086:4;37079:17;37198:3;37654:5;37784:1;37779:3;37775:11;37768:18;;37921:2;37915:4;37911:13;37907:2;37903:22;37898:3;37890:36;37962:2;37956:4;37952:13;37944:21;;37546:680;37981:4;37546:680;;;38155:1;38150:3;38146:11;38139:18;;38206:2;38200:4;38196:13;38192:2;38188:22;38183:3;38175:36;38076:2;38070:4;38066:13;38058:21;;37546:680;;;37550:430;38265:3;38260;38256:13;38380:2;38375:3;38371:12;38364:19;;38443:6;38438:3;38431:19;36621:1840;;36525:1943;;;:::o;20668:164::-;20765:4;20789:18;:25;20808:5;20789:25;;;;;;;;;;;;;;;:35;20815:8;20789:35;;;;;;;;;;;;;;;;;;;;;;;;;20782:42;;20668:164;;;;:::o;35147:159::-;;;;;:::o;35965:158::-;;;;;:::o;22881:2246::-;23004:20;23027:13;;23004:36;;23080:1;23055:21;23073:2;23055:17;:21::i;:::-;:26;23051:58;;;23090:19;;;;;;;;;;;;;;23051:58;23136:1;23124:8;:13;23120:44;;;23146:18;;;;;;;;;;;;;;23120:44;23177:61;23207:1;23211:2;23215:12;23229:8;23177:21;:61::i;:::-;23781:1;9083:2;23752:1;:25;;23751:31;23739:8;:44;23713:18;:22;23732:2;23713:22;;;;;;;;;;;;;;;;:70;;;;;;;;;;;9859:3;24182:29;24209:1;24197:8;:13;24182:14;:29::i;:::-;:56;;9600:3;24119:15;:41;;24077:21;24095:2;24077:17;:21::i;:::-;:84;:162;24026:17;:31;24044:12;24026:31;;;;;;;;;;;:213;;;;24256:20;24279:12;24256:35;;24306:11;24335:8;24320:12;:23;24306:37;;24382:1;24364:2;:14;;;:19;24360:635;;24404:313;24460:12;24456:2;24435:38;;24452:1;24435:38;;;;;;;;;;;;24501:69;24540:1;24544:2;24548:14;;;;;;24564:5;24501:30;:69::i;:::-;24496:174;;24606:40;;;;;;;;;;;;;;24496:174;24712:3;24697:12;:18;24404:313;;24798:12;24781:13;;:29;24777:43;;24812:8;;;24777:43;24360:635;;;24861:119;24917:14;;;;;;24913:2;24892:40;;24909:1;24892:40;;;;;;;;;;;;24975:3;24960:12;:18;24861:119;;24360:635;25025:12;25009:13;:28;;;;23490:1559;;25059:60;25088:1;25092:2;25096:12;25110:8;25059:20;:60::i;:::-;22993:2134;22881:2246;;;:::o;40559:296::-;40642:7;40662:20;40685:4;40662:27;;40705:9;40700:118;40724:5;:12;40720:1;:16;40700:118;;;40773:33;40783:12;40797:5;40803:1;40797:8;;;;;;;;:::i;:::-;;;;;;;;40773:9;:33::i;:::-;40758:48;;40738:3;;;;;:::i;:::-;;;;40700:118;;;;40835:12;40828:19;;;40559:296;;;;:::o;16472:295::-;16538:31;;:::i;:::-;16615:6;16582:9;:14;;:41;;;;;;;;;;;9600:3;16668:6;:32;;16634:9;:24;;:67;;;;;;;;;;;16758:1;9716:8;16731:6;:23;:28;;16712:9;:16;;:47;;;;;;;;;;;16472:295;;;:::o;19269:142::-;19327:14;19388:5;19378:15;;19269:142;;;:::o;46766:149::-;46829:7;46860:1;46856;:5;:51;;46887:20;46902:1;46905;46887:14;:20::i;:::-;46856:51;;;46864:20;46879:1;46882;46864:14;:20::i;:::-;46856:51;46849:58;;46766:149;;;;:::o;46923:268::-;46991:13;47098:1;47092:4;47085:15;47127:1;47121:4;47114:15;47168:4;47162;47152:21;47143:30;;46923:268;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:410:1:-;84:5;109:65;125:48;166:6;125:48;:::i;:::-;109:65;:::i;:::-;100:74;;197:6;190:5;183:21;235:4;228:5;224:16;273:3;264:6;259:3;255:16;252:25;249:112;;;280:79;;:::i;:::-;249:112;370:41;404:6;399:3;394;370:41;:::i;:::-;90:327;7:410;;;;;:::o;423:412::-;501:5;526:66;542:49;584:6;542:49;:::i;:::-;526:66;:::i;:::-;517:75;;615:6;608:5;601:21;653:4;646:5;642:16;691:3;682:6;677:3;673:16;670:25;667:112;;;698:79;;:::i;:::-;667:112;788:41;822:6;817:3;812;788:41;:::i;:::-;507:328;423:412;;;;;:::o;841:139::-;887:5;925:6;912:20;903:29;;941:33;968:5;941:33;:::i;:::-;841:139;;;;:::o;1003:568::-;1076:8;1086:6;1136:3;1129:4;1121:6;1117:17;1113:27;1103:122;;1144:79;;:::i;:::-;1103:122;1257:6;1244:20;1234:30;;1287:18;1279:6;1276:30;1273:117;;;1309:79;;:::i;:::-;1273:117;1423:4;1415:6;1411:17;1399:29;;1477:3;1469:4;1461:6;1457:17;1447:8;1443:32;1440:41;1437:128;;;1484:79;;:::i;:::-;1437:128;1003:568;;;;;:::o;1577:133::-;1620:5;1658:6;1645:20;1636:29;;1674:30;1698:5;1674:30;:::i;:::-;1577:133;;;;:::o;1716:139::-;1762:5;1800:6;1787:20;1778:29;;1816:33;1843:5;1816:33;:::i;:::-;1716:139;;;;:::o;1861:137::-;1906:5;1944:6;1931:20;1922:29;;1960:32;1986:5;1960:32;:::i;:::-;1861:137;;;;:::o;2004:141::-;2060:5;2091:6;2085:13;2076:22;;2107:32;2133:5;2107:32;:::i;:::-;2004:141;;;;:::o;2164:338::-;2219:5;2268:3;2261:4;2253:6;2249:17;2245:27;2235:122;;2276:79;;:::i;:::-;2235:122;2393:6;2380:20;2418:78;2492:3;2484:6;2477:4;2469:6;2465:17;2418:78;:::i;:::-;2409:87;;2225:277;2164:338;;;;:::o;2522:340::-;2578:5;2627:3;2620:4;2612:6;2608:17;2604:27;2594:122;;2635:79;;:::i;:::-;2594:122;2752:6;2739:20;2777:79;2852:3;2844:6;2837:4;2829:6;2825:17;2777:79;:::i;:::-;2768:88;;2584:278;2522:340;;;;:::o;2868:139::-;2914:5;2952:6;2939:20;2930:29;;2968:33;2995:5;2968:33;:::i;:::-;2868:139;;;;:::o;3013:329::-;3072:6;3121:2;3109:9;3100:7;3096:23;3092:32;3089:119;;;3127:79;;:::i;:::-;3089:119;3247:1;3272:53;3317:7;3308:6;3297:9;3293:22;3272:53;:::i;:::-;3262:63;;3218:117;3013:329;;;;:::o;3348:474::-;3416:6;3424;3473:2;3461:9;3452:7;3448:23;3444:32;3441:119;;;3479:79;;:::i;:::-;3441:119;3599:1;3624:53;3669:7;3660:6;3649:9;3645:22;3624:53;:::i;:::-;3614:63;;3570:117;3726:2;3752:53;3797:7;3788:6;3777:9;3773:22;3752:53;:::i;:::-;3742:63;;3697:118;3348:474;;;;;:::o;3828:619::-;3905:6;3913;3921;3970:2;3958:9;3949:7;3945:23;3941:32;3938:119;;;3976:79;;:::i;:::-;3938:119;4096:1;4121:53;4166:7;4157:6;4146:9;4142:22;4121:53;:::i;:::-;4111:63;;4067:117;4223:2;4249:53;4294:7;4285:6;4274:9;4270:22;4249:53;:::i;:::-;4239:63;;4194:118;4351:2;4377:53;4422:7;4413:6;4402:9;4398:22;4377:53;:::i;:::-;4367:63;;4322:118;3828:619;;;;;:::o;4453:943::-;4548:6;4556;4564;4572;4621:3;4609:9;4600:7;4596:23;4592:33;4589:120;;;4628:79;;:::i;:::-;4589:120;4748:1;4773:53;4818:7;4809:6;4798:9;4794:22;4773:53;:::i;:::-;4763:63;;4719:117;4875:2;4901:53;4946:7;4937:6;4926:9;4922:22;4901:53;:::i;:::-;4891:63;;4846:118;5003:2;5029:53;5074:7;5065:6;5054:9;5050:22;5029:53;:::i;:::-;5019:63;;4974:118;5159:2;5148:9;5144:18;5131:32;5190:18;5182:6;5179:30;5176:117;;;5212:79;;:::i;:::-;5176:117;5317:62;5371:7;5362:6;5351:9;5347:22;5317:62;:::i;:::-;5307:72;;5102:287;4453:943;;;;;;;:::o;5402:468::-;5467:6;5475;5524:2;5512:9;5503:7;5499:23;5495:32;5492:119;;;5530:79;;:::i;:::-;5492:119;5650:1;5675:53;5720:7;5711:6;5700:9;5696:22;5675:53;:::i;:::-;5665:63;;5621:117;5777:2;5803:50;5845:7;5836:6;5825:9;5821:22;5803:50;:::i;:::-;5793:60;;5748:115;5402:468;;;;;:::o;5876:474::-;5944:6;5952;6001:2;5989:9;5980:7;5976:23;5972:32;5969:119;;;6007:79;;:::i;:::-;5969:119;6127:1;6152:53;6197:7;6188:6;6177:9;6173:22;6152:53;:::i;:::-;6142:63;;6098:117;6254:2;6280:53;6325:7;6316:6;6305:9;6301:22;6280:53;:::i;:::-;6270:63;;6225:118;5876:474;;;;;:::o;6356:559::-;6442:6;6450;6499:2;6487:9;6478:7;6474:23;6470:32;6467:119;;;6505:79;;:::i;:::-;6467:119;6653:1;6642:9;6638:17;6625:31;6683:18;6675:6;6672:30;6669:117;;;6705:79;;:::i;:::-;6669:117;6818:80;6890:7;6881:6;6870:9;6866:22;6818:80;:::i;:::-;6800:98;;;;6596:312;6356:559;;;;;:::o;6921:329::-;6980:6;7029:2;7017:9;7008:7;7004:23;7000:32;6997:119;;;7035:79;;:::i;:::-;6997:119;7155:1;7180:53;7225:7;7216:6;7205:9;7201:22;7180:53;:::i;:::-;7170:63;;7126:117;6921:329;;;;:::o;7256:327::-;7314:6;7363:2;7351:9;7342:7;7338:23;7334:32;7331:119;;;7369:79;;:::i;:::-;7331:119;7489:1;7514:52;7558:7;7549:6;7538:9;7534:22;7514:52;:::i;:::-;7504:62;;7460:116;7256:327;;;;:::o;7589:349::-;7658:6;7707:2;7695:9;7686:7;7682:23;7678:32;7675:119;;;7713:79;;:::i;:::-;7675:119;7833:1;7858:63;7913:7;7904:6;7893:9;7889:22;7858:63;:::i;:::-;7848:73;;7804:127;7589:349;;;;:::o;7944:509::-;8013:6;8062:2;8050:9;8041:7;8037:23;8033:32;8030:119;;;8068:79;;:::i;:::-;8030:119;8216:1;8205:9;8201:17;8188:31;8246:18;8238:6;8235:30;8232:117;;;8268:79;;:::i;:::-;8232:117;8373:63;8428:7;8419:6;8408:9;8404:22;8373:63;:::i;:::-;8363:73;;8159:287;7944:509;;;;:::o;8459:329::-;8518:6;8567:2;8555:9;8546:7;8542:23;8538:32;8535:119;;;8573:79;;:::i;:::-;8535:119;8693:1;8718:53;8763:7;8754:6;8743:9;8739:22;8718:53;:::i;:::-;8708:63;;8664:117;8459:329;;;;:::o;8794:704::-;8889:6;8897;8905;8954:2;8942:9;8933:7;8929:23;8925:32;8922:119;;;8960:79;;:::i;:::-;8922:119;9080:1;9105:53;9150:7;9141:6;9130:9;9126:22;9105:53;:::i;:::-;9095:63;;9051:117;9235:2;9224:9;9220:18;9207:32;9266:18;9258:6;9255:30;9252:117;;;9288:79;;:::i;:::-;9252:117;9401:80;9473:7;9464:6;9453:9;9449:22;9401:80;:::i;:::-;9383:98;;;;9178:313;8794:704;;;;;:::o;9504:108::-;9581:24;9599:5;9581:24;:::i;:::-;9576:3;9569:37;9504:108;;:::o;9618:118::-;9705:24;9723:5;9705:24;:::i;:::-;9700:3;9693:37;9618:118;;:::o;9742:157::-;9847:45;9867:24;9885:5;9867:24;:::i;:::-;9847:45;:::i;:::-;9842:3;9835:58;9742:157;;:::o;9905:99::-;9976:21;9991:5;9976:21;:::i;:::-;9971:3;9964:34;9905:99;;:::o;10010:109::-;10091:21;10106:5;10091:21;:::i;:::-;10086:3;10079:34;10010:109;;:::o;10125:118::-;10212:24;10230:5;10212:24;:::i;:::-;10207:3;10200:37;10125:118;;:::o;10249:360::-;10335:3;10363:38;10395:5;10363:38;:::i;:::-;10417:70;10480:6;10475:3;10417:70;:::i;:::-;10410:77;;10496:52;10541:6;10536:3;10529:4;10522:5;10518:16;10496:52;:::i;:::-;10573:29;10595:6;10573:29;:::i;:::-;10568:3;10564:39;10557:46;;10339:270;10249:360;;;;:::o;10615:364::-;10703:3;10731:39;10764:5;10731:39;:::i;:::-;10786:71;10850:6;10845:3;10786:71;:::i;:::-;10779:78;;10866:52;10911:6;10906:3;10899:4;10892:5;10888:16;10866:52;:::i;:::-;10943:29;10965:6;10943:29;:::i;:::-;10938:3;10934:39;10927:46;;10707:272;10615:364;;;;:::o;10985:377::-;11091:3;11119:39;11152:5;11119:39;:::i;:::-;11174:89;11256:6;11251:3;11174:89;:::i;:::-;11167:96;;11272:52;11317:6;11312:3;11305:4;11298:5;11294:16;11272:52;:::i;:::-;11349:6;11344:3;11340:16;11333:23;;11095:267;10985:377;;;;:::o;11392:845::-;11495:3;11532:5;11526:12;11561:36;11587:9;11561:36;:::i;:::-;11613:89;11695:6;11690:3;11613:89;:::i;:::-;11606:96;;11733:1;11722:9;11718:17;11749:1;11744:137;;;;11895:1;11890:341;;;;11711:520;;11744:137;11828:4;11824:9;11813;11809:25;11804:3;11797:38;11864:6;11859:3;11855:16;11848:23;;11744:137;;11890:341;11957:38;11989:5;11957:38;:::i;:::-;12017:1;12031:154;12045:6;12042:1;12039:13;12031:154;;;12119:7;12113:14;12109:1;12104:3;12100:11;12093:35;12169:1;12160:7;12156:15;12145:26;;12067:4;12064:1;12060:12;12055:17;;12031:154;;;12214:6;12209:3;12205:16;12198:23;;11897:334;;11711:520;;11499:738;;11392:845;;;;:::o;12243:366::-;12385:3;12406:67;12470:2;12465:3;12406:67;:::i;:::-;12399:74;;12482:93;12571:3;12482:93;:::i;:::-;12600:2;12595:3;12591:12;12584:19;;12243:366;;;:::o;12615:::-;12757:3;12778:67;12842:2;12837:3;12778:67;:::i;:::-;12771:74;;12854:93;12943:3;12854:93;:::i;:::-;12972:2;12967:3;12963:12;12956:19;;12615:366;;;:::o;12987:::-;13129:3;13150:67;13214:2;13209:3;13150:67;:::i;:::-;13143:74;;13226:93;13315:3;13226:93;:::i;:::-;13344:2;13339:3;13335:12;13328:19;;12987:366;;;:::o;13359:::-;13501:3;13522:67;13586:2;13581:3;13522:67;:::i;:::-;13515:74;;13598:93;13687:3;13598:93;:::i;:::-;13716:2;13711:3;13707:12;13700:19;;13359:366;;;:::o;13731:::-;13873:3;13894:67;13958:2;13953:3;13894:67;:::i;:::-;13887:74;;13970:93;14059:3;13970:93;:::i;:::-;14088:2;14083:3;14079:12;14072:19;;13731:366;;;:::o;14103:::-;14245:3;14266:67;14330:2;14325:3;14266:67;:::i;:::-;14259:74;;14342:93;14431:3;14342:93;:::i;:::-;14460:2;14455:3;14451:12;14444:19;;14103:366;;;:::o;14475:::-;14617:3;14638:67;14702:2;14697:3;14638:67;:::i;:::-;14631:74;;14714:93;14803:3;14714:93;:::i;:::-;14832:2;14827:3;14823:12;14816:19;;14475:366;;;:::o;14847:::-;14989:3;15010:67;15074:2;15069:3;15010:67;:::i;:::-;15003:74;;15086:93;15175:3;15086:93;:::i;:::-;15204:2;15199:3;15195:12;15188:19;;14847:366;;;:::o;15219:::-;15361:3;15382:67;15446:2;15441:3;15382:67;:::i;:::-;15375:74;;15458:93;15547:3;15458:93;:::i;:::-;15576:2;15571:3;15567:12;15560:19;;15219:366;;;:::o;15591:::-;15733:3;15754:67;15818:2;15813:3;15754:67;:::i;:::-;15747:74;;15830:93;15919:3;15830:93;:::i;:::-;15948:2;15943:3;15939:12;15932:19;;15591:366;;;:::o;15963:::-;16105:3;16126:67;16190:2;16185:3;16126:67;:::i;:::-;16119:74;;16202:93;16291:3;16202:93;:::i;:::-;16320:2;16315:3;16311:12;16304:19;;15963:366;;;:::o;16335:400::-;16495:3;16516:84;16598:1;16593:3;16516:84;:::i;:::-;16509:91;;16609:93;16698:3;16609:93;:::i;:::-;16727:1;16722:3;16718:11;16711:18;;16335:400;;;:::o;16741:366::-;16883:3;16904:67;16968:2;16963:3;16904:67;:::i;:::-;16897:74;;16980:93;17069:3;16980:93;:::i;:::-;17098:2;17093:3;17089:12;17082:19;;16741:366;;;:::o;17113:::-;17255:3;17276:67;17340:2;17335:3;17276:67;:::i;:::-;17269:74;;17352:93;17441:3;17352:93;:::i;:::-;17470:2;17465:3;17461:12;17454:19;;17113:366;;;:::o;17485:::-;17627:3;17648:67;17712:2;17707:3;17648:67;:::i;:::-;17641:74;;17724:93;17813:3;17724:93;:::i;:::-;17842:2;17837:3;17833:12;17826:19;;17485:366;;;:::o;17857:::-;17999:3;18020:67;18084:2;18079:3;18020:67;:::i;:::-;18013:74;;18096:93;18185:3;18096:93;:::i;:::-;18214:2;18209:3;18205:12;18198:19;;17857:366;;;:::o;18229:::-;18371:3;18392:67;18456:2;18451:3;18392:67;:::i;:::-;18385:74;;18468:93;18557:3;18468:93;:::i;:::-;18586:2;18581:3;18577:12;18570:19;;18229:366;;;:::o;18601:::-;18743:3;18764:67;18828:2;18823:3;18764:67;:::i;:::-;18757:74;;18840:93;18929:3;18840:93;:::i;:::-;18958:2;18953:3;18949:12;18942:19;;18601:366;;;:::o;18973:398::-;19132:3;19153:83;19234:1;19229:3;19153:83;:::i;:::-;19146:90;;19245:93;19334:3;19245:93;:::i;:::-;19363:1;19358:3;19354:11;19347:18;;18973:398;;;:::o;19377:366::-;19519:3;19540:67;19604:2;19599:3;19540:67;:::i;:::-;19533:74;;19616:93;19705:3;19616:93;:::i;:::-;19734:2;19729:3;19725:12;19718:19;;19377:366;;;:::o;19821:695::-;19978:4;19973:3;19969:14;20065:4;20058:5;20054:16;20048:23;20084:63;20141:4;20136:3;20132:14;20118:12;20084:63;:::i;:::-;19993:164;20249:4;20242:5;20238:16;20232:23;20268:61;20323:4;20318:3;20314:14;20300:12;20268:61;:::i;:::-;20167:172;20423:4;20416:5;20412:16;20406:23;20442:57;20493:4;20488:3;20484:14;20470:12;20442:57;:::i;:::-;20349:160;19947:569;19821:695;;:::o;20522:118::-;20609:24;20627:5;20609:24;:::i;:::-;20604:3;20597:37;20522:118;;:::o;20646:105::-;20721:23;20738:5;20721:23;:::i;:::-;20716:3;20709:36;20646:105;;:::o;20757:256::-;20869:3;20884:75;20955:3;20946:6;20884:75;:::i;:::-;20984:2;20979:3;20975:12;20968:19;;21004:3;20997:10;;20757:256;;;;:::o;21019:695::-;21297:3;21319:92;21407:3;21398:6;21319:92;:::i;:::-;21312:99;;21428:95;21519:3;21510:6;21428:95;:::i;:::-;21421:102;;21540:148;21684:3;21540:148;:::i;:::-;21533:155;;21705:3;21698:10;;21019:695;;;;;:::o;21720:379::-;21904:3;21926:147;22069:3;21926:147;:::i;:::-;21919:154;;22090:3;22083:10;;21720:379;;;:::o;22105:222::-;22198:4;22236:2;22225:9;22221:18;22213:26;;22249:71;22317:1;22306:9;22302:17;22293:6;22249:71;:::i;:::-;22105:222;;;;:::o;22333:640::-;22528:4;22566:3;22555:9;22551:19;22543:27;;22580:71;22648:1;22637:9;22633:17;22624:6;22580:71;:::i;:::-;22661:72;22729:2;22718:9;22714:18;22705:6;22661:72;:::i;:::-;22743;22811:2;22800:9;22796:18;22787:6;22743:72;:::i;:::-;22862:9;22856:4;22852:20;22847:2;22836:9;22832:18;22825:48;22890:76;22961:4;22952:6;22890:76;:::i;:::-;22882:84;;22333:640;;;;;;;:::o;22979:210::-;23066:4;23104:2;23093:9;23089:18;23081:26;;23117:65;23179:1;23168:9;23164:17;23155:6;23117:65;:::i;:::-;22979:210;;;;:::o;23195:222::-;23288:4;23326:2;23315:9;23311:18;23303:26;;23339:71;23407:1;23396:9;23392:17;23383:6;23339:71;:::i;:::-;23195:222;;;;:::o;23423:313::-;23536:4;23574:2;23563:9;23559:18;23551:26;;23623:9;23617:4;23613:20;23609:1;23598:9;23594:17;23587:47;23651:78;23724:4;23715:6;23651:78;:::i;:::-;23643:86;;23423:313;;;;:::o;23742:419::-;23908:4;23946:2;23935:9;23931:18;23923:26;;23995:9;23989:4;23985:20;23981:1;23970:9;23966:17;23959:47;24023:131;24149:4;24023:131;:::i;:::-;24015:139;;23742:419;;;:::o;24167:::-;24333:4;24371:2;24360:9;24356:18;24348:26;;24420:9;24414:4;24410:20;24406:1;24395:9;24391:17;24384:47;24448:131;24574:4;24448:131;:::i;:::-;24440:139;;24167:419;;;:::o;24592:::-;24758:4;24796:2;24785:9;24781:18;24773:26;;24845:9;24839:4;24835:20;24831:1;24820:9;24816:17;24809:47;24873:131;24999:4;24873:131;:::i;:::-;24865:139;;24592:419;;;:::o;25017:::-;25183:4;25221:2;25210:9;25206:18;25198:26;;25270:9;25264:4;25260:20;25256:1;25245:9;25241:17;25234:47;25298:131;25424:4;25298:131;:::i;:::-;25290:139;;25017:419;;;:::o;25442:::-;25608:4;25646:2;25635:9;25631:18;25623:26;;25695:9;25689:4;25685:20;25681:1;25670:9;25666:17;25659:47;25723:131;25849:4;25723:131;:::i;:::-;25715:139;;25442:419;;;:::o;25867:::-;26033:4;26071:2;26060:9;26056:18;26048:26;;26120:9;26114:4;26110:20;26106:1;26095:9;26091:17;26084:47;26148:131;26274:4;26148:131;:::i;:::-;26140:139;;25867:419;;;:::o;26292:::-;26458:4;26496:2;26485:9;26481:18;26473:26;;26545:9;26539:4;26535:20;26531:1;26520:9;26516:17;26509:47;26573:131;26699:4;26573:131;:::i;:::-;26565:139;;26292:419;;;:::o;26717:::-;26883:4;26921:2;26910:9;26906:18;26898:26;;26970:9;26964:4;26960:20;26956:1;26945:9;26941:17;26934:47;26998:131;27124:4;26998:131;:::i;:::-;26990:139;;26717:419;;;:::o;27142:::-;27308:4;27346:2;27335:9;27331:18;27323:26;;27395:9;27389:4;27385:20;27381:1;27370:9;27366:17;27359:47;27423:131;27549:4;27423:131;:::i;:::-;27415:139;;27142:419;;;:::o;27567:::-;27733:4;27771:2;27760:9;27756:18;27748:26;;27820:9;27814:4;27810:20;27806:1;27795:9;27791:17;27784:47;27848:131;27974:4;27848:131;:::i;:::-;27840:139;;27567:419;;;:::o;27992:::-;28158:4;28196:2;28185:9;28181:18;28173:26;;28245:9;28239:4;28235:20;28231:1;28220:9;28216:17;28209:47;28273:131;28399:4;28273:131;:::i;:::-;28265:139;;27992:419;;;:::o;28417:::-;28583:4;28621:2;28610:9;28606:18;28598:26;;28670:9;28664:4;28660:20;28656:1;28645:9;28641:17;28634:47;28698:131;28824:4;28698:131;:::i;:::-;28690:139;;28417:419;;;:::o;28842:::-;29008:4;29046:2;29035:9;29031:18;29023:26;;29095:9;29089:4;29085:20;29081:1;29070:9;29066:17;29059:47;29123:131;29249:4;29123:131;:::i;:::-;29115:139;;28842:419;;;:::o;29267:::-;29433:4;29471:2;29460:9;29456:18;29448:26;;29520:9;29514:4;29510:20;29506:1;29495:9;29491:17;29484:47;29548:131;29674:4;29548:131;:::i;:::-;29540:139;;29267:419;;;:::o;29692:::-;29858:4;29896:2;29885:9;29881:18;29873:26;;29945:9;29939:4;29935:20;29931:1;29920:9;29916:17;29909:47;29973:131;30099:4;29973:131;:::i;:::-;29965:139;;29692:419;;;:::o;30117:::-;30283:4;30321:2;30310:9;30306:18;30298:26;;30370:9;30364:4;30360:20;30356:1;30345:9;30341:17;30334:47;30398:131;30524:4;30398:131;:::i;:::-;30390:139;;30117:419;;;:::o;30542:::-;30708:4;30746:2;30735:9;30731:18;30723:26;;30795:9;30789:4;30785:20;30781:1;30770:9;30766:17;30759:47;30823:131;30949:4;30823:131;:::i;:::-;30815:139;;30542:419;;;:::o;30967:::-;31133:4;31171:2;31160:9;31156:18;31148:26;;31220:9;31214:4;31210:20;31206:1;31195:9;31191:17;31184:47;31248:131;31374:4;31248:131;:::i;:::-;31240:139;;30967:419;;;:::o;31392:342::-;31545:4;31583:2;31572:9;31568:18;31560:26;;31596:131;31724:1;31713:9;31709:17;31700:6;31596:131;:::i;:::-;31392:342;;;;:::o;31740:222::-;31833:4;31871:2;31860:9;31856:18;31848:26;;31884:71;31952:1;31941:9;31937:17;31928:6;31884:71;:::i;:::-;31740:222;;;;:::o;31968:129::-;32002:6;32029:20;;:::i;:::-;32019:30;;32058:33;32086:4;32078:6;32058:33;:::i;:::-;31968:129;;;:::o;32103:75::-;32136:6;32169:2;32163:9;32153:19;;32103:75;:::o;32184:307::-;32245:4;32335:18;32327:6;32324:30;32321:56;;;32357:18;;:::i;:::-;32321:56;32395:29;32417:6;32395:29;:::i;:::-;32387:37;;32479:4;32473;32469:15;32461:23;;32184:307;;;:::o;32497:308::-;32559:4;32649:18;32641:6;32638:30;32635:56;;;32671:18;;:::i;:::-;32635:56;32709:29;32731:6;32709:29;:::i;:::-;32701:37;;32793:4;32787;32783:15;32775:23;;32497:308;;;:::o;32811:141::-;32860:4;32883:3;32875:11;;32906:3;32903:1;32896:14;32940:4;32937:1;32927:18;32919:26;;32811:141;;;:::o;32958:98::-;33009:6;33043:5;33037:12;33027:22;;32958:98;;;:::o;33062:99::-;33114:6;33148:5;33142:12;33132:22;;33062:99;;;:::o;33167:168::-;33250:11;33284:6;33279:3;33272:19;33324:4;33319:3;33315:14;33300:29;;33167:168;;;;:::o;33341:147::-;33442:11;33479:3;33464:18;;33341:147;;;;:::o;33494:169::-;33578:11;33612:6;33607:3;33600:19;33652:4;33647:3;33643:14;33628:29;;33494:169;;;;:::o;33669:148::-;33771:11;33808:3;33793:18;;33669:148;;;;:::o;33823:305::-;33863:3;33882:20;33900:1;33882:20;:::i;:::-;33877:25;;33916:20;33934:1;33916:20;:::i;:::-;33911:25;;34070:1;34002:66;33998:74;33995:1;33992:81;33989:107;;;34076:18;;:::i;:::-;33989:107;34120:1;34117;34113:9;34106:16;;33823:305;;;;:::o;34134:348::-;34174:7;34197:20;34215:1;34197:20;:::i;:::-;34192:25;;34231:20;34249:1;34231:20;:::i;:::-;34226:25;;34419:1;34351:66;34347:74;34344:1;34341:81;34336:1;34329:9;34322:17;34318:105;34315:131;;;34426:18;;:::i;:::-;34315:131;34474:1;34471;34467:9;34456:20;;34134:348;;;;:::o;34488:96::-;34525:7;34554:24;34572:5;34554:24;:::i;:::-;34543:35;;34488:96;;;:::o;34590:90::-;34624:7;34667:5;34660:13;34653:21;34642:32;;34590:90;;;:::o;34686:77::-;34723:7;34752:5;34741:16;;34686:77;;;:::o;34769:149::-;34805:7;34845:66;34838:5;34834:78;34823:89;;34769:149;;;:::o;34924:126::-;34961:7;35001:42;34994:5;34990:54;34979:65;;34924:126;;;:::o;35056:77::-;35093:7;35122:5;35111:16;;35056:77;;;:::o;35139:101::-;35175:7;35215:18;35208:5;35204:30;35193:41;;35139:101;;;:::o;35246:154::-;35330:6;35325:3;35320;35307:30;35392:1;35383:6;35378:3;35374:16;35367:27;35246:154;;;:::o;35406:307::-;35474:1;35484:113;35498:6;35495:1;35492:13;35484:113;;;35583:1;35578:3;35574:11;35568:18;35564:1;35559:3;35555:11;35548:39;35520:2;35517:1;35513:10;35508:15;;35484:113;;;35615:6;35612:1;35609:13;35606:101;;;35695:1;35686:6;35681:3;35677:16;35670:27;35606:101;35455:258;35406:307;;;:::o;35719:320::-;35763:6;35800:1;35794:4;35790:12;35780:22;;35847:1;35841:4;35837:12;35868:18;35858:81;;35924:4;35916:6;35912:17;35902:27;;35858:81;35986:2;35978:6;35975:14;35955:18;35952:38;35949:84;;;36005:18;;:::i;:::-;35949:84;35770:269;35719:320;;;:::o;36045:281::-;36128:27;36150:4;36128:27;:::i;:::-;36120:6;36116:40;36258:6;36246:10;36243:22;36222:18;36210:10;36207:34;36204:62;36201:88;;;36269:18;;:::i;:::-;36201:88;36309:10;36305:2;36298:22;36088:238;36045:281;;:::o;36332:233::-;36371:3;36394:24;36412:5;36394:24;:::i;:::-;36385:33;;36440:66;36433:5;36430:77;36427:103;;;36510:18;;:::i;:::-;36427:103;36557:1;36550:5;36546:13;36539:20;;36332:233;;;:::o;36571:100::-;36610:7;36639:26;36659:5;36639:26;:::i;:::-;36628:37;;36571:100;;;:::o;36677:94::-;36716:7;36745:20;36759:5;36745:20;:::i;:::-;36734:31;;36677:94;;;:::o;36777:180::-;36825:77;36822:1;36815:88;36922:4;36919:1;36912:15;36946:4;36943:1;36936:15;36963:180;37011:77;37008:1;37001:88;37108:4;37105:1;37098:15;37132:4;37129:1;37122:15;37149:180;37197:77;37194:1;37187:88;37294:4;37291:1;37284:15;37318:4;37315:1;37308:15;37335:180;37383:77;37380:1;37373:88;37480:4;37477:1;37470:15;37504:4;37501:1;37494:15;37521:117;37630:1;37627;37620:12;37644:117;37753:1;37750;37743:12;37767:117;37876:1;37873;37866:12;37890:117;37999:1;37996;37989:12;38013:117;38122:1;38119;38112:12;38136:117;38245:1;38242;38235:12;38259:102;38300:6;38351:2;38347:7;38342:2;38335:5;38331:14;38327:28;38317:38;;38259:102;;;:::o;38367:94::-;38400:8;38448:5;38444:2;38440:14;38419:35;;38367:94;;;:::o;38467:176::-;38607:28;38603:1;38595:6;38591:14;38584:52;38467:176;:::o;38649:225::-;38789:34;38785:1;38777:6;38773:14;38766:58;38858:8;38853:2;38845:6;38841:15;38834:33;38649:225;:::o;38880:233::-;39020:34;39016:1;39008:6;39004:14;38997:58;39089:16;39084:2;39076:6;39072:15;39065:41;38880:233;:::o;39119:169::-;39259:21;39255:1;39247:6;39243:14;39236:45;39119:169;:::o;39294:173::-;39434:25;39430:1;39422:6;39418:14;39411:49;39294:173;:::o;39473:163::-;39613:15;39609:1;39601:6;39597:14;39590:39;39473:163;:::o;39642:177::-;39782:29;39778:1;39770:6;39766:14;39759:53;39642:177;:::o;39825:176::-;39965:28;39961:1;39953:6;39949:14;39942:52;39825:176;:::o;40007:230::-;40147:34;40143:1;40135:6;40131:14;40124:58;40216:13;40211:2;40203:6;40199:15;40192:38;40007:230;:::o;40243:169::-;40383:21;40379:1;40371:6;40367:14;40360:45;40243:169;:::o;40418:235::-;40558:34;40554:1;40546:6;40542:14;40535:58;40627:18;40622:2;40614:6;40610:15;40603:43;40418:235;:::o;40659:155::-;40799:7;40795:1;40787:6;40783:14;40776:31;40659:155;:::o;40820:182::-;40960:34;40956:1;40948:6;40944:14;40937:58;40820:182;:::o;41008:226::-;41148:34;41144:1;41136:6;41132:14;41125:58;41217:9;41212:2;41204:6;41200:15;41193:34;41008:226;:::o;41240:250::-;41380:34;41376:1;41368:6;41364:14;41357:58;41449:33;41444:2;41436:6;41432:15;41425:58;41240:250;:::o;41496:174::-;41636:26;41632:1;41624:6;41620:14;41613:50;41496:174;:::o;41676:168::-;41816:20;41812:1;41804:6;41800:14;41793:44;41676:168;:::o;41850:174::-;41990:26;41986:1;41978:6;41974:14;41967:50;41850:174;:::o;42030:114::-;;:::o;42150:182::-;42290:34;42286:1;42278:6;42274:14;42267:58;42150:182;:::o;42338:122::-;42411:24;42429:5;42411:24;:::i;:::-;42404:5;42401:35;42391:63;;42450:1;42447;42440:12;42391:63;42338:122;:::o;42466:116::-;42536:21;42551:5;42536:21;:::i;:::-;42529:5;42526:32;42516:60;;42572:1;42569;42562:12;42516:60;42466:116;:::o;42588:122::-;42661:24;42679:5;42661:24;:::i;:::-;42654:5;42651:35;42641:63;;42700:1;42697;42690:12;42641:63;42588:122;:::o;42716:120::-;42788:23;42805:5;42788:23;:::i;:::-;42781:5;42778:34;42768:62;;42826:1;42823;42816:12;42768:62;42716:120;:::o;42842:122::-;42915:24;42933:5;42915:24;:::i;:::-;42908:5;42905:35;42895:63;;42954:1;42951;42944:12;42895:63;42842:122;:::o

Swarm Source

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