ETH Price: $3,432.55 (-1.58%)
Gas: 2 Gwei

Token

PixelHeroes (PHERO)
 

Overview

Max Total Supply

1,686 PHERO

Holders

509

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
3 PHERO
0x145df293285d76a035b6932510869ebd43db6671
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:
PixelHeroes

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-10-11
*/

// SPDX-License-Identifier: MIT

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

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

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



// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;



/**
 * @dev Interface of an ERC721A compliant contract.
 */
interface IERC721A is IERC721, IERC721Metadata {
    /**
     * 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();

    // Compiler will pack this into a single 256bit word.
    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;
    }

    // Compiler will pack this into a single 256bit word.
    struct AddressData {
        // Realistically, 2**64-1 is more than enough.
        uint64 balance;
        // Keeps track of mint count with minimal overhead for tokenomics.
        uint64 numberMinted;
        // Keeps track of burn count with minimal overhead for tokenomics.
        uint64 numberBurned;
        // For miscellaneous variable(s) pertaining to the address
        // (e.g. number of whitelist mint slots used).
        // If there are multiple variables, please pack them into a uint64.
        uint64 aux;
    }

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


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

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

// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;


/**
 * @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 Context, ERC165, IERC721A {
    using Address for address;
    using Strings for uint256;

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

    // The number of tokens burned.
    uint256 internal _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 _ownershipOf implementation for details.
    mapping(uint256 => TokenOwnership) internal _ownerships;

    // Mapping owner address to address data
    mapping(address => AddressData) private _addressData;

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

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

    /**
     * @dev Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens.
     */
    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();
        }
    }

    /**
     * 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 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 override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return uint256(_addressData[owner].balance);
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return uint256(_addressData[owner].numberMinted);
    }

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

    /**
     * Returns the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return _addressData[owner].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 {
        _addressData[owner].aux = aux;
    }

    /**
     * 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) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr) if (curr < _currentIndex) {
                TokenOwnership memory ownership = _ownerships[curr];
                if (!ownership.burned) {
                    if (ownership.addr != address(0)) {
                        return ownership;
                    }
                    // 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.
                    while (true) {
                        curr--;
                        ownership = _ownerships[curr];
                        if (ownership.addr != address(0)) {
                            return ownership;
                        }
                    }
                }
            }
        }
        revert OwnerQueryForNonexistentToken();
    }

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

    /**
     * @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, 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 overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

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

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

        _approve(to, tokenId, owner);
    }

    /**
     * @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 == _msgSender()) revert ApproveToCaller();

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_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 {
        _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.isContract()) 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 && !_ownerships[tokenId].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 (to == address(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 {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

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

            if (to.isContract()) {
                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 (to == address(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 {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            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 {
        TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

        if (prevOwnership.addr != from) revert TransferFromIncorrectOwner();

        bool isApprovedOrOwner = (_msgSender() == from ||
            isApprovedForAll(from, _msgSender()) ||
            getApproved(tokenId) == _msgSender());

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

        _beforeTokenTransfers(from, to, tokenId, 1);

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

        // 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 {
            _addressData[from].balance -= 1;
            _addressData[to].balance += 1;

            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = to;
            currSlot.startTimestamp = uint64(block.timestamp);

            // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

        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 {
        TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

        address from = prevOwnership.addr;

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSender() == from ||
                isApprovedForAll(from, _msgSender()) ||
                getApproved(tokenId) == _msgSender());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

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

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

        // 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 {
            AddressData storage addressData = _addressData[from];
            addressData.balance -= 1;
            addressData.numberBurned += 1;

            // Keep track of who burned the token, and the timestamp of burning.
            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = from;
            currSlot.startTimestamp = uint64(block.timestamp);
            currSlot.burned = true;

            // If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

        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 Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(
        address to,
        uint256 tokenId,
        address owner
    ) private {
        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @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 IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
            return retval == 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 {}
}
// 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);
}




// 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);
    }
}
// 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 functionCallWithValue(target, data, 0, "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");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or 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 {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // 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);
        }
    }
}


// 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)
        }
    }
}


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;



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

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

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

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

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

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

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

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

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



// Contract ERC721A From: Chiru Labs



pragma solidity >=0.8.6;


interface HeroToken {
    function updateRewardOnMint(address _to, uint256 _amount) external;

    function updateReward(address _from, address _to) external;

    function getReward(address _to) external;

    function spend(address _from, uint256 _amount) external;
}

contract PixelHeroes is ERC721A, Ownable {

    uint public price = 0.02 ether;
    uint public maxSupply = 4000;
    uint public maxSupplyPre = 1000;
    uint public maxTx = 3;

    mapping(address => uint256) public _preSaleCounter;

    bytes32 public merkleRoot;

    bool private mintOpen = false;
    bool private presaleOpen = false;

    string internal baseTokenURI = '';
    
    HeroToken public heroToken;



    constructor() ERC721A("PixelHeroes", "PHERO") {}

    function toggleMint() external onlyOwner {
        mintOpen = !mintOpen;
    }

    function togglePresale() external onlyOwner {
        presaleOpen = !presaleOpen;
    }
    
    function setPrice(uint newPrice) external onlyOwner {
        price = newPrice;
    }
    
    function setBaseTokenURI(string calldata _uri) external onlyOwner {
        baseTokenURI = _uri;
    }

    function setMerkleRoot(bytes32 root) external onlyOwner {
        merkleRoot = root;
    }
    
    function setMaxSupply(uint newSupply) external onlyOwner {
        maxSupply = newSupply;
    }

    function setToken(address _contract) external onlyOwner {
        heroToken = HeroToken(_contract);
    }
    
    function setMaxTx(uint newMax) external onlyOwner {
        maxTx = newMax;
    }

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

    function buyTo(address to, uint qty) external onlyOwner {
        _mintTo(to, qty);
    }

    function buyPre(uint qty, bytes32[] memory proof) external payable {
        require(presaleOpen, "store closed");
        require(
            _preSaleCounter[msg.sender] + qty <= maxTx,
            "Exceeded max available to purchase"
        );
        _preSaleCounter[msg.sender] =
            _preSaleCounter[msg.sender] +
            qty;
        require(verify(proof), "address not in whitelist");
        _buyPre(qty);
    }
    
    function buy(uint qty) external payable {
        require(mintOpen, "store closed");
        require(
            _preSaleCounter[msg.sender] + qty <= maxTx,
            "Exceeded max available to purchase"
        );
        _preSaleCounter[msg.sender] =
            _preSaleCounter[msg.sender] +
            qty;
        _buy(qty);
    }

    function _buy(uint qty) internal {
        require(qty <= maxTx && qty > 0, "TRANSACTION: qty of mints not alowed");
        require(totalSupply() + qty <= maxSupply, "reached max supply");
        require(msg.value >= price, "PAYMENT: invalid value");
        _mintTo(_msgSender(), qty);
        heroToken.updateRewardOnMint(_msgSender(), qty);
    }

    function _buyPre(uint qty) internal {
        require(qty <= maxTx && qty > 0, "TRANSACTION: qty of mints not alowed");
        require(totalSupply() + qty <= maxSupplyPre, "reached max supply of preSale");
        uint free = balanceOf(_msgSender()) == 0 ? 1 : 0;
        require(msg.value >= price * (qty - free), "PAYMENT: invalid value");
        _mintTo(_msgSender(), qty);
        heroToken.updateRewardOnMint(_msgSender(), qty);
    }

    function _mintTo(address to, uint qty) internal {
        require(qty + totalSupply() <= maxSupply, "SUPPLY: Value exceeds totalSupply");
        _mint(to, qty);
    }
    
    function withdraw() external onlyOwner {
        payable(_msgSender()).transfer(address(this).balance);
    }

    function verify(bytes32[] memory proof) internal view returns (bool) {
        bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
        return MerkleProof.verify(proof, merkleRoot, leaf);
    }

    function airdrop(address[] calldata _users) external onlyOwner {
        for (uint256 i = 0; i < _users.length; i++) {
            _safeMint(_users[i], 1);
        }
    }

    function claimTokens() external {
        heroToken.updateReward(msg.sender, address(0));
        heroToken.getReward(msg.sender);
    }

    function spendTokens(uint256 _amount) external {
        heroToken.spend(msg.sender, _amount);
    }

    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 tokenId,
        uint256 quantity
    ) internal virtual override {
        super._beforeTokenTransfers(from, to, tokenId, quantity);
        if (from != address(0)) {
            heroToken.updateReward(from, to);
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"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":[{"internalType":"address","name":"","type":"address"}],"name":"_preSaleCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"qty","type":"uint256"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"qty","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"buyPre","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"qty","type":"uint256"}],"name":"buyTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"heroToken","outputs":[{"internalType":"contract HeroToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyPre","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setBaseTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMax","type":"uint256"}],"name":"setMaxTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"setToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"spendTokens","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":"toggleMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"togglePresale","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":"nonpayable","type":"function"}]

608060405266470de4df820000600955610fa0600a556103e8600b556003600c556000600f60006101000a81548160ff0219169083151502179055506000600f60016101000a81548160ff0219169083151502179055506040518060200160405280600081525060109081620000769190620004a0565b503480156200008457600080fd5b506040518060400160405280600b81526020017f506978656c4865726f65730000000000000000000000000000000000000000008152506040518060400160405280600581526020017f504845524f0000000000000000000000000000000000000000000000000000008152508160029081620001029190620004a0565b508060039081620001149190620004a0565b50620001256200015360201b60201c565b60008190555050506200014d620001416200015860201b60201c565b6200016060201b60201c565b62000587565b600090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620002a857607f821691505b602082108103620002be57620002bd62000260565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620003287fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002e9565b620003348683620002e9565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620003816200037b62000375846200034c565b62000356565b6200034c565b9050919050565b6000819050919050565b6200039d8362000360565b620003b5620003ac8262000388565b848454620002f6565b825550505050565b600090565b620003cc620003bd565b620003d981848462000392565b505050565b5b818110156200040157620003f5600082620003c2565b600181019050620003df565b5050565b601f82111562000450576200041a81620002c4565b6200042584620002d9565b8101602085101562000435578190505b6200044d6200044485620002d9565b830182620003de565b50505b505050565b600082821c905092915050565b6000620004756000198460080262000455565b1980831691505092915050565b600062000490838362000462565b9150826002028217905092915050565b620004ab8262000226565b67ffffffffffffffff811115620004c757620004c662000231565b5b620004d382546200028f565b620004e082828562000405565b600060209050601f83116001811462000518576000841562000503578287015190505b6200050f858262000482565b8655506200057f565b601f1984166200052886620002c4565b60005b8281101562000552578489015182556001820191506020850194506020810190506200052b565b868310156200057257848901516200056e601f89168262000462565b8355505b6001600288020188555050505b505050505050565b61474b80620005976000396000f3fe6080604052600436106102305760003560e01c8063715018a61161012e578063a22cb465116100ab578063d3dd5fe01161006f578063d3dd5fe0146107dc578063d5abeb01146107f3578063d96a094a1461081e578063e985e9c51461083a578063f2fde38b1461087757610230565b8063a22cb465146106f9578063b88d4fde14610722578063bbca57151461074b578063bc33718214610776578063c87b56dd1461079f57610230565b80638da5cb5b116100f25780638da5cb5b146106265780638e39f5151461065157806391b7f5ed1461067a57806395d89b41146106a3578063a035b1fe146106ce57610230565b8063715018a614610576578063729ad39e1461058d5780637437681e146105b65780637cb64759146105e1578063818144921461060a57610230565b80632eb4a7ab116101bc57806348c54b9d1161018057806348c54b9d14610491578063596599ae146104a85780636352211e146104d35780636f8b44b01461051057806370a082311461053957610230565b80632eb4a7ab146103e657806330176e1314610411578063343937431461043a5780633ccfd60b1461045157806342842e0e1461046857610230565b806309bd4c311161020357806309bd4c3114610303578063144fa6d71461032c57806318160ddd1461035557806323b872dd1461038057806327b1425a146103a957610230565b806301ffc9a71461023557806306fdde0314610272578063081812fc1461029d578063095ea7b3146102da575b600080fd5b34801561024157600080fd5b5061025c600480360381019061025791906132cb565b6108a0565b6040516102699190613313565b60405180910390f35b34801561027e57600080fd5b50610287610982565b60405161029491906133be565b60405180910390f35b3480156102a957600080fd5b506102c460048036038101906102bf9190613416565b610a14565b6040516102d19190613484565b60405180910390f35b3480156102e657600080fd5b5061030160048036038101906102fc91906134cb565b610a90565b005b34801561030f57600080fd5b5061032a600480360381019061032591906134cb565b610b94565b005b34801561033857600080fd5b50610353600480360381019061034e919061350b565b610baa565b005b34801561036157600080fd5b5061036a610bf6565b6040516103779190613547565b60405180910390f35b34801561038c57600080fd5b506103a760048036038101906103a29190613562565b610c0d565b005b3480156103b557600080fd5b506103d060048036038101906103cb919061350b565b610c1d565b6040516103dd9190613547565b60405180910390f35b3480156103f257600080fd5b506103fb610c35565b60405161040891906135ce565b60405180910390f35b34801561041d57600080fd5b506104386004803603810190610433919061364e565b610c3b565b005b34801561044657600080fd5b5061044f610c59565b005b34801561045d57600080fd5b50610466610c8d565b005b34801561047457600080fd5b5061048f600480360381019061048a9190613562565b610ce5565b005b34801561049d57600080fd5b506104a6610d05565b005b3480156104b457600080fd5b506104bd610e24565b6040516104ca9190613547565b60405180910390f35b3480156104df57600080fd5b506104fa60048036038101906104f59190613416565b610e2a565b6040516105079190613484565b60405180910390f35b34801561051c57600080fd5b5061053760048036038101906105329190613416565b610e40565b005b34801561054557600080fd5b50610560600480360381019061055b919061350b565b610e52565b60405161056d9190613547565b60405180910390f35b34801561058257600080fd5b5061058b610f21565b005b34801561059957600080fd5b506105b460048036038101906105af91906136f1565b610f35565b005b3480156105c257600080fd5b506105cb610f95565b6040516105d89190613547565b60405180910390f35b3480156105ed57600080fd5b506106086004803603810190610603919061376a565b610f9b565b005b610624600480360381019061061f91906138d5565b610fad565b005b34801561063257600080fd5b5061063b61116e565b6040516106489190613484565b60405180910390f35b34801561065d57600080fd5b5061067860048036038101906106739190613416565b611198565b005b34801561068657600080fd5b506106a1600480360381019061069c9190613416565b61122a565b005b3480156106af57600080fd5b506106b861123c565b6040516106c591906133be565b60405180910390f35b3480156106da57600080fd5b506106e36112ce565b6040516106f09190613547565b60405180910390f35b34801561070557600080fd5b50610720600480360381019061071b919061395d565b6112d4565b005b34801561072e57600080fd5b5061074960048036038101906107449190613a52565b61144b565b005b34801561075757600080fd5b506107606114c3565b60405161076d9190613b34565b60405180910390f35b34801561078257600080fd5b5061079d60048036038101906107989190613416565b6114e9565b005b3480156107ab57600080fd5b506107c660048036038101906107c19190613416565b6114fb565b6040516107d391906133be565b60405180910390f35b3480156107e857600080fd5b506107f1611599565b005b3480156107ff57600080fd5b506108086115cd565b6040516108159190613547565b60405180910390f35b61083860048036038101906108339190613416565b6115d3565b005b34801561084657600080fd5b50610861600480360381019061085c9190613b4f565b61174b565b60405161086e9190613313565b60405180910390f35b34801561088357600080fd5b5061089e6004803603810190610899919061350b565b6117df565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061096b57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061097b575061097a82611862565b5b9050919050565b60606002805461099190613bbe565b80601f01602080910402602001604051908101604052809291908181526020018280546109bd90613bbe565b8015610a0a5780601f106109df57610100808354040283529160200191610a0a565b820191906000526020600020905b8154815290600101906020018083116109ed57829003601f168201915b5050505050905090565b6000610a1f826118cc565b610a55576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a9b82610e2a565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b02576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610b2161191a565b73ffffffffffffffffffffffffffffffffffffffff1614610b8457610b4d81610b4861191a565b61174b565b610b83576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b610b8f838383611922565b505050565b610b9c6119d4565b610ba68282611a52565b5050565b610bb26119d4565b80601160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000610c00611ab7565b6001546000540303905090565b610c18838383611abc565b505050565b600d6020528060005260406000206000915090505481565b600e5481565b610c436119d4565b818160109182610c54929190613d9c565b505050565b610c616119d4565b600f60019054906101000a900460ff1615600f60016101000a81548160ff021916908315150217905550565b610c956119d4565b610c9d61191a565b73ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610ce2573d6000803e3d6000fd5b50565b610d008383836040518060200160405280600081525061144b565b505050565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d230af3a3360006040518363ffffffff1660e01b8152600401610d63929190613e6c565b600060405180830381600087803b158015610d7d57600080fd5b505af1158015610d91573d6000803e3d6000fd5b50505050601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c00007b0336040518263ffffffff1660e01b8152600401610df09190613484565b600060405180830381600087803b158015610e0a57600080fd5b505af1158015610e1e573d6000803e3d6000fd5b50505050565b600b5481565b6000610e3582611f70565b600001519050919050565b610e486119d4565b80600a8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610eb9576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b610f296119d4565b610f3360006121fb565b565b610f3d6119d4565b60005b82829050811015610f9057610f7d838383818110610f6157610f60613e95565b5b9050602002016020810190610f76919061350b565b60016122c1565b8080610f8890613ef3565b915050610f40565b505050565b600c5481565b610fa36119d4565b80600e8190555050565b600f60019054906101000a900460ff16610ffc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff390613f87565b60405180910390fd5b600c5482600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461104a9190613fa7565b111561108b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110829061404d565b60405180910390fd5b81600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546110d69190613fa7565b600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611122816122df565b611161576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611158906140b9565b60405180910390fd5b61116a82612320565b5050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663af7d6ca333836040518363ffffffff1660e01b81526004016111f59291906140d9565b600060405180830381600087803b15801561120f57600080fd5b505af1158015611223573d6000803e3d6000fd5b5050505050565b6112326119d4565b8060098190555050565b60606003805461124b90613bbe565b80601f016020809104026020016040519081016040528092919081815260200182805461127790613bbe565b80156112c45780601f10611299576101008083540402835291602001916112c4565b820191906000526020600020905b8154815290600101906020018083116112a757829003601f168201915b5050505050905090565b60095481565b6112dc61191a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611340576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806007600061134d61191a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166113fa61191a565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161143f9190613313565b60405180910390a35050565b611456848484611abc565b6114758373ffffffffffffffffffffffffffffffffffffffff166124f5565b156114bd5761148684848484612518565b6114bc576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6114f16119d4565b80600c8190555050565b6060611506826118cc565b61153c576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611546612668565b905060008151036115665760405180602001604052806000815250611591565b80611570846126fa565b60405160200161158192919061413e565b6040516020818303038152906040525b915050919050565b6115a16119d4565b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b600a5481565b600f60009054906101000a900460ff16611622576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161990613f87565b60405180910390fd5b600c5481600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546116709190613fa7565b11156116b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a89061404d565b60405180910390fd5b80600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546116fc9190613fa7565b600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506117488161285a565b50565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6117e76119d4565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611856576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161184d906141d4565b60405180910390fd5b61185f816121fb565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6000816118d7611ab7565b111580156118e6575060005482105b8015611913575060046000838152602001908152602001600020600001601c9054906101000a900460ff16155b9050919050565b600033905090565b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6119dc61191a565b73ffffffffffffffffffffffffffffffffffffffff166119fa61116e565b73ffffffffffffffffffffffffffffffffffffffff1614611a50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4790614240565b60405180910390fd5b565b600a54611a5d610bf6565b82611a689190613fa7565b1115611aa9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aa0906142d2565b60405180910390fd5b611ab382826129f1565b5050565b600090565b6000611ac782611f70565b90508373ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614611b32576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16611b5361191a565b73ffffffffffffffffffffffffffffffffffffffff161480611b825750611b8185611b7c61191a565b61174b565b5b80611bc75750611b9061191a565b73ffffffffffffffffffffffffffffffffffffffff16611baf84610a14565b73ffffffffffffffffffffffffffffffffffffffff16145b905080611c00576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611c66576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c738585856001612ccb565b611c7f60008487611922565b6001600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600460008581526020019081526020016000209050848160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550428160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006001850190506000600460008381526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603611efe576000548214611efd57878160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084602001518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b505050828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611f698585856001612da1565b5050505050565b611f7861321c565b600082905080611f86611ab7565b116121c4576000548110156121c3576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff161515151581525050905080604001516121c157600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146120a55780925050506121f6565b5b6001156121c057818060019003925050600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146121bb5780925050506121f6565b6120a6565b5b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6122db828260405180602001604052806000815250612da7565b5050565b600080336040516020016122f3919061433a565b60405160208183030381529060405280519060200120905061231883600e5483613167565b915050919050565b600c5481111580156123325750600081115b612371576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612368906143c7565b60405180910390fd5b600b548161237d610bf6565b6123879190613fa7565b11156123c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123bf90614433565b60405180910390fd5b6000806123db6123d661191a565b610e52565b146123e75760006123ea565b60015b60ff16905080826123fb9190614453565b6009546124089190614487565b34101561244a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244190614515565b60405180910390fd5b61245b61245561191a565b83611a52565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cc240c016124a161191a565b846040518363ffffffff1660e01b81526004016124bf9291906140d9565b600060405180830381600087803b1580156124d957600080fd5b505af11580156124ed573d6000803e3d6000fd5b505050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261253e61191a565b8786866040518563ffffffff1660e01b8152600401612560949392919061458a565b6020604051808303816000875af192505050801561259c57506040513d601f19601f8201168201806040525081019061259991906145eb565b60015b612615573d80600081146125cc576040519150601f19603f3d011682016040523d82523d6000602084013e6125d1565b606091505b50600081510361260d576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606010805461267790613bbe565b80601f01602080910402602001604051908101604052809291908181526020018280546126a390613bbe565b80156126f05780601f106126c5576101008083540402835291602001916126f0565b820191906000526020600020905b8154815290600101906020018083116126d357829003601f168201915b5050505050905090565b606060008203612741576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612855565b600082905060005b6000821461277357808061275c90613ef3565b915050600a8261276c9190614647565b9150612749565b60008167ffffffffffffffff81111561278f5761278e613797565b5b6040519080825280601f01601f1916602001820160405280156127c15781602001600182028036833780820191505090505b5090505b6000851461284e576001826127da9190614453565b9150600a856127e99190614678565b60306127f59190613fa7565b60f81b81838151811061280b5761280a613e95565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856128479190614647565b94506127c5565b8093505050505b919050565b600c54811115801561286c5750600081115b6128ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128a2906143c7565b60405180910390fd5b600a54816128b7610bf6565b6128c19190613fa7565b1115612902576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128f9906146f5565b60405180910390fd5b600954341015612947576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161293e90614515565b60405180910390fd5b61295861295261191a565b82611a52565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cc240c0161299e61191a565b836040518363ffffffff1660e01b81526004016129bc9291906140d9565b600060405180830381600087803b1580156129d657600080fd5b505af11580156129ea573d6000803e3d6000fd5b5050505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612a5d576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008203612a97576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612aa46000848385612ccb565b81600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555081600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550826004600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426004600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000819050600083820190505b818060010192508573ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808210612c4757816000819055505050612cc66000848385612da1565b505050565b612cd78484848461317e565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612d9b57601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d230af3a85856040518363ffffffff1660e01b8152600401612d68929190613e6c565b600060405180830381600087803b158015612d8257600080fd5b505af1158015612d96573d6000803e3d6000fd5b505050505b50505050565b50505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612e13576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008303612e4d576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e5a6000858386612ccb565b82600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555082600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550836004600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426004600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060008190506000848201905061301b8673ffffffffffffffffffffffffffffffffffffffff166124f5565b156130e0575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46130906000878480600101955087612518565b6130c6576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082106130215782600054146130db57600080fd5b61314b565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082106130e1575b8160008190555050506131616000858386612da1565b50505050565b6000826131748584613184565b1490509392505050565b50505050565b60008082905060005b84518110156131cf576131ba828683815181106131ad576131ac613e95565b5b60200260200101516131da565b915080806131c790613ef3565b91505061318d565b508091505092915050565b60008183106131f2576131ed8284613205565b6131fd565b6131fc8383613205565b5b905092915050565b600082600052816020526040600020905092915050565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6132a881613273565b81146132b357600080fd5b50565b6000813590506132c58161329f565b92915050565b6000602082840312156132e1576132e0613269565b5b60006132ef848285016132b6565b91505092915050565b60008115159050919050565b61330d816132f8565b82525050565b60006020820190506133286000830184613304565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561336857808201518184015260208101905061334d565b60008484015250505050565b6000601f19601f8301169050919050565b60006133908261332e565b61339a8185613339565b93506133aa81856020860161334a565b6133b381613374565b840191505092915050565b600060208201905081810360008301526133d88184613385565b905092915050565b6000819050919050565b6133f3816133e0565b81146133fe57600080fd5b50565b600081359050613410816133ea565b92915050565b60006020828403121561342c5761342b613269565b5b600061343a84828501613401565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061346e82613443565b9050919050565b61347e81613463565b82525050565b60006020820190506134996000830184613475565b92915050565b6134a881613463565b81146134b357600080fd5b50565b6000813590506134c58161349f565b92915050565b600080604083850312156134e2576134e1613269565b5b60006134f0858286016134b6565b925050602061350185828601613401565b9150509250929050565b60006020828403121561352157613520613269565b5b600061352f848285016134b6565b91505092915050565b613541816133e0565b82525050565b600060208201905061355c6000830184613538565b92915050565b60008060006060848603121561357b5761357a613269565b5b6000613589868287016134b6565b935050602061359a868287016134b6565b92505060406135ab86828701613401565b9150509250925092565b6000819050919050565b6135c8816135b5565b82525050565b60006020820190506135e360008301846135bf565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261360e5761360d6135e9565b5b8235905067ffffffffffffffff81111561362b5761362a6135ee565b5b602083019150836001820283011115613647576136466135f3565b5b9250929050565b6000806020838503121561366557613664613269565b5b600083013567ffffffffffffffff8111156136835761368261326e565b5b61368f858286016135f8565b92509250509250929050565b60008083601f8401126136b1576136b06135e9565b5b8235905067ffffffffffffffff8111156136ce576136cd6135ee565b5b6020830191508360208202830111156136ea576136e96135f3565b5b9250929050565b6000806020838503121561370857613707613269565b5b600083013567ffffffffffffffff8111156137265761372561326e565b5b6137328582860161369b565b92509250509250929050565b613747816135b5565b811461375257600080fd5b50565b6000813590506137648161373e565b92915050565b6000602082840312156137805761377f613269565b5b600061378e84828501613755565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6137cf82613374565b810181811067ffffffffffffffff821117156137ee576137ed613797565b5b80604052505050565b600061380161325f565b905061380d82826137c6565b919050565b600067ffffffffffffffff82111561382d5761382c613797565b5b602082029050602081019050919050565b600061385161384c84613812565b6137f7565b90508083825260208201905060208402830185811115613874576138736135f3565b5b835b8181101561389d57806138898882613755565b845260208401935050602081019050613876565b5050509392505050565b600082601f8301126138bc576138bb6135e9565b5b81356138cc84826020860161383e565b91505092915050565b600080604083850312156138ec576138eb613269565b5b60006138fa85828601613401565b925050602083013567ffffffffffffffff81111561391b5761391a61326e565b5b613927858286016138a7565b9150509250929050565b61393a816132f8565b811461394557600080fd5b50565b60008135905061395781613931565b92915050565b6000806040838503121561397457613973613269565b5b6000613982858286016134b6565b925050602061399385828601613948565b9150509250929050565b600080fd5b600067ffffffffffffffff8211156139bd576139bc613797565b5b6139c682613374565b9050602081019050919050565b82818337600083830152505050565b60006139f56139f0846139a2565b6137f7565b905082815260208101848484011115613a1157613a1061399d565b5b613a1c8482856139d3565b509392505050565b600082601f830112613a3957613a386135e9565b5b8135613a498482602086016139e2565b91505092915050565b60008060008060808587031215613a6c57613a6b613269565b5b6000613a7a878288016134b6565b9450506020613a8b878288016134b6565b9350506040613a9c87828801613401565b925050606085013567ffffffffffffffff811115613abd57613abc61326e565b5b613ac987828801613a24565b91505092959194509250565b6000819050919050565b6000613afa613af5613af084613443565b613ad5565b613443565b9050919050565b6000613b0c82613adf565b9050919050565b6000613b1e82613b01565b9050919050565b613b2e81613b13565b82525050565b6000602082019050613b496000830184613b25565b92915050565b60008060408385031215613b6657613b65613269565b5b6000613b74858286016134b6565b9250506020613b85858286016134b6565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613bd657607f821691505b602082108103613be957613be8613b8f565b5b50919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613c5c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613c1f565b613c668683613c1f565b95508019841693508086168417925050509392505050565b6000613c99613c94613c8f846133e0565b613ad5565b6133e0565b9050919050565b6000819050919050565b613cb383613c7e565b613cc7613cbf82613ca0565b848454613c2c565b825550505050565b600090565b613cdc613ccf565b613ce7818484613caa565b505050565b5b81811015613d0b57613d00600082613cd4565b600181019050613ced565b5050565b601f821115613d5057613d2181613bfa565b613d2a84613c0f565b81016020851015613d39578190505b613d4d613d4585613c0f565b830182613cec565b50505b505050565b600082821c905092915050565b6000613d7360001984600802613d55565b1980831691505092915050565b6000613d8c8383613d62565b9150826002028217905092915050565b613da68383613bef565b67ffffffffffffffff811115613dbf57613dbe613797565b5b613dc98254613bbe565b613dd4828285613d0f565b6000601f831160018114613e035760008415613df1578287013590505b613dfb8582613d80565b865550613e63565b601f198416613e1186613bfa565b60005b82811015613e3957848901358255600182019150602085019450602081019050613e14565b86831015613e565784890135613e52601f891682613d62565b8355505b6001600288020188555050505b50505050505050565b6000604082019050613e816000830185613475565b613e8e6020830184613475565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613efe826133e0565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613f3057613f2f613ec4565b5b600182019050919050565b7f73746f726520636c6f7365640000000000000000000000000000000000000000600082015250565b6000613f71600c83613339565b9150613f7c82613f3b565b602082019050919050565b60006020820190508181036000830152613fa081613f64565b9050919050565b6000613fb2826133e0565b9150613fbd836133e0565b9250828201905080821115613fd557613fd4613ec4565b5b92915050565b7f4578636565646564206d617820617661696c61626c6520746f2070757263686160008201527f7365000000000000000000000000000000000000000000000000000000000000602082015250565b6000614037602283613339565b915061404282613fdb565b604082019050919050565b600060208201905081810360008301526140668161402a565b9050919050565b7f61646472657373206e6f7420696e2077686974656c6973740000000000000000600082015250565b60006140a3601883613339565b91506140ae8261406d565b602082019050919050565b600060208201905081810360008301526140d281614096565b9050919050565b60006040820190506140ee6000830185613475565b6140fb6020830184613538565b9392505050565b600081905092915050565b60006141188261332e565b6141228185614102565b935061413281856020860161334a565b80840191505092915050565b600061414a828561410d565b9150614156828461410d565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006141be602683613339565b91506141c982614162565b604082019050919050565b600060208201905081810360008301526141ed816141b1565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061422a602083613339565b9150614235826141f4565b602082019050919050565b600060208201905081810360008301526142598161421d565b9050919050565b7f535550504c593a2056616c7565206578636565647320746f74616c537570706c60008201527f7900000000000000000000000000000000000000000000000000000000000000602082015250565b60006142bc602183613339565b91506142c782614260565b604082019050919050565b600060208201905081810360008301526142eb816142af565b9050919050565b60008160601b9050919050565b600061430a826142f2565b9050919050565b600061431c826142ff565b9050919050565b61433461432f82613463565b614311565b82525050565b60006143468284614323565b60148201915081905092915050565b7f5452414e53414354494f4e3a20717479206f66206d696e7473206e6f7420616c60008201527f6f77656400000000000000000000000000000000000000000000000000000000602082015250565b60006143b1602483613339565b91506143bc82614355565b604082019050919050565b600060208201905081810360008301526143e0816143a4565b9050919050565b7f72656163686564206d617820737570706c79206f662070726553616c65000000600082015250565b600061441d601d83613339565b9150614428826143e7565b602082019050919050565b6000602082019050818103600083015261444c81614410565b9050919050565b600061445e826133e0565b9150614469836133e0565b925082820390508181111561448157614480613ec4565b5b92915050565b6000614492826133e0565b915061449d836133e0565b92508282026144ab816133e0565b915082820484148315176144c2576144c1613ec4565b5b5092915050565b7f5041594d454e543a20696e76616c69642076616c756500000000000000000000600082015250565b60006144ff601683613339565b915061450a826144c9565b602082019050919050565b6000602082019050818103600083015261452e816144f2565b9050919050565b600081519050919050565b600082825260208201905092915050565b600061455c82614535565b6145668185614540565b935061457681856020860161334a565b61457f81613374565b840191505092915050565b600060808201905061459f6000830187613475565b6145ac6020830186613475565b6145b96040830185613538565b81810360608301526145cb8184614551565b905095945050505050565b6000815190506145e58161329f565b92915050565b60006020828403121561460157614600613269565b5b600061460f848285016145d6565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614652826133e0565b915061465d836133e0565b92508261466d5761466c614618565b5b828204905092915050565b6000614683826133e0565b915061468e836133e0565b92508261469e5761469d614618565b5b828206905092915050565b7f72656163686564206d617820737570706c790000000000000000000000000000600082015250565b60006146df601283613339565b91506146ea826146a9565b602082019050919050565b6000602082019050818103600083015261470e816146d2565b905091905056fea26469706673582212202da309b6afc79deb6f3f12b61de6fd4e92e1c21ed68d5f743372f53fbf05671764736f6c63430008110033

Deployed Bytecode

0x6080604052600436106102305760003560e01c8063715018a61161012e578063a22cb465116100ab578063d3dd5fe01161006f578063d3dd5fe0146107dc578063d5abeb01146107f3578063d96a094a1461081e578063e985e9c51461083a578063f2fde38b1461087757610230565b8063a22cb465146106f9578063b88d4fde14610722578063bbca57151461074b578063bc33718214610776578063c87b56dd1461079f57610230565b80638da5cb5b116100f25780638da5cb5b146106265780638e39f5151461065157806391b7f5ed1461067a57806395d89b41146106a3578063a035b1fe146106ce57610230565b8063715018a614610576578063729ad39e1461058d5780637437681e146105b65780637cb64759146105e1578063818144921461060a57610230565b80632eb4a7ab116101bc57806348c54b9d1161018057806348c54b9d14610491578063596599ae146104a85780636352211e146104d35780636f8b44b01461051057806370a082311461053957610230565b80632eb4a7ab146103e657806330176e1314610411578063343937431461043a5780633ccfd60b1461045157806342842e0e1461046857610230565b806309bd4c311161020357806309bd4c3114610303578063144fa6d71461032c57806318160ddd1461035557806323b872dd1461038057806327b1425a146103a957610230565b806301ffc9a71461023557806306fdde0314610272578063081812fc1461029d578063095ea7b3146102da575b600080fd5b34801561024157600080fd5b5061025c600480360381019061025791906132cb565b6108a0565b6040516102699190613313565b60405180910390f35b34801561027e57600080fd5b50610287610982565b60405161029491906133be565b60405180910390f35b3480156102a957600080fd5b506102c460048036038101906102bf9190613416565b610a14565b6040516102d19190613484565b60405180910390f35b3480156102e657600080fd5b5061030160048036038101906102fc91906134cb565b610a90565b005b34801561030f57600080fd5b5061032a600480360381019061032591906134cb565b610b94565b005b34801561033857600080fd5b50610353600480360381019061034e919061350b565b610baa565b005b34801561036157600080fd5b5061036a610bf6565b6040516103779190613547565b60405180910390f35b34801561038c57600080fd5b506103a760048036038101906103a29190613562565b610c0d565b005b3480156103b557600080fd5b506103d060048036038101906103cb919061350b565b610c1d565b6040516103dd9190613547565b60405180910390f35b3480156103f257600080fd5b506103fb610c35565b60405161040891906135ce565b60405180910390f35b34801561041d57600080fd5b506104386004803603810190610433919061364e565b610c3b565b005b34801561044657600080fd5b5061044f610c59565b005b34801561045d57600080fd5b50610466610c8d565b005b34801561047457600080fd5b5061048f600480360381019061048a9190613562565b610ce5565b005b34801561049d57600080fd5b506104a6610d05565b005b3480156104b457600080fd5b506104bd610e24565b6040516104ca9190613547565b60405180910390f35b3480156104df57600080fd5b506104fa60048036038101906104f59190613416565b610e2a565b6040516105079190613484565b60405180910390f35b34801561051c57600080fd5b5061053760048036038101906105329190613416565b610e40565b005b34801561054557600080fd5b50610560600480360381019061055b919061350b565b610e52565b60405161056d9190613547565b60405180910390f35b34801561058257600080fd5b5061058b610f21565b005b34801561059957600080fd5b506105b460048036038101906105af91906136f1565b610f35565b005b3480156105c257600080fd5b506105cb610f95565b6040516105d89190613547565b60405180910390f35b3480156105ed57600080fd5b506106086004803603810190610603919061376a565b610f9b565b005b610624600480360381019061061f91906138d5565b610fad565b005b34801561063257600080fd5b5061063b61116e565b6040516106489190613484565b60405180910390f35b34801561065d57600080fd5b5061067860048036038101906106739190613416565b611198565b005b34801561068657600080fd5b506106a1600480360381019061069c9190613416565b61122a565b005b3480156106af57600080fd5b506106b861123c565b6040516106c591906133be565b60405180910390f35b3480156106da57600080fd5b506106e36112ce565b6040516106f09190613547565b60405180910390f35b34801561070557600080fd5b50610720600480360381019061071b919061395d565b6112d4565b005b34801561072e57600080fd5b5061074960048036038101906107449190613a52565b61144b565b005b34801561075757600080fd5b506107606114c3565b60405161076d9190613b34565b60405180910390f35b34801561078257600080fd5b5061079d60048036038101906107989190613416565b6114e9565b005b3480156107ab57600080fd5b506107c660048036038101906107c19190613416565b6114fb565b6040516107d391906133be565b60405180910390f35b3480156107e857600080fd5b506107f1611599565b005b3480156107ff57600080fd5b506108086115cd565b6040516108159190613547565b60405180910390f35b61083860048036038101906108339190613416565b6115d3565b005b34801561084657600080fd5b50610861600480360381019061085c9190613b4f565b61174b565b60405161086e9190613313565b60405180910390f35b34801561088357600080fd5b5061089e6004803603810190610899919061350b565b6117df565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061096b57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061097b575061097a82611862565b5b9050919050565b60606002805461099190613bbe565b80601f01602080910402602001604051908101604052809291908181526020018280546109bd90613bbe565b8015610a0a5780601f106109df57610100808354040283529160200191610a0a565b820191906000526020600020905b8154815290600101906020018083116109ed57829003601f168201915b5050505050905090565b6000610a1f826118cc565b610a55576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a9b82610e2a565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b02576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610b2161191a565b73ffffffffffffffffffffffffffffffffffffffff1614610b8457610b4d81610b4861191a565b61174b565b610b83576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b610b8f838383611922565b505050565b610b9c6119d4565b610ba68282611a52565b5050565b610bb26119d4565b80601160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000610c00611ab7565b6001546000540303905090565b610c18838383611abc565b505050565b600d6020528060005260406000206000915090505481565b600e5481565b610c436119d4565b818160109182610c54929190613d9c565b505050565b610c616119d4565b600f60019054906101000a900460ff1615600f60016101000a81548160ff021916908315150217905550565b610c956119d4565b610c9d61191a565b73ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610ce2573d6000803e3d6000fd5b50565b610d008383836040518060200160405280600081525061144b565b505050565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d230af3a3360006040518363ffffffff1660e01b8152600401610d63929190613e6c565b600060405180830381600087803b158015610d7d57600080fd5b505af1158015610d91573d6000803e3d6000fd5b50505050601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c00007b0336040518263ffffffff1660e01b8152600401610df09190613484565b600060405180830381600087803b158015610e0a57600080fd5b505af1158015610e1e573d6000803e3d6000fd5b50505050565b600b5481565b6000610e3582611f70565b600001519050919050565b610e486119d4565b80600a8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610eb9576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900467ffffffffffffffff1667ffffffffffffffff169050919050565b610f296119d4565b610f3360006121fb565b565b610f3d6119d4565b60005b82829050811015610f9057610f7d838383818110610f6157610f60613e95565b5b9050602002016020810190610f76919061350b565b60016122c1565b8080610f8890613ef3565b915050610f40565b505050565b600c5481565b610fa36119d4565b80600e8190555050565b600f60019054906101000a900460ff16610ffc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff390613f87565b60405180910390fd5b600c5482600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461104a9190613fa7565b111561108b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110829061404d565b60405180910390fd5b81600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546110d69190613fa7565b600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611122816122df565b611161576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611158906140b9565b60405180910390fd5b61116a82612320565b5050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663af7d6ca333836040518363ffffffff1660e01b81526004016111f59291906140d9565b600060405180830381600087803b15801561120f57600080fd5b505af1158015611223573d6000803e3d6000fd5b5050505050565b6112326119d4565b8060098190555050565b60606003805461124b90613bbe565b80601f016020809104026020016040519081016040528092919081815260200182805461127790613bbe565b80156112c45780601f10611299576101008083540402835291602001916112c4565b820191906000526020600020905b8154815290600101906020018083116112a757829003601f168201915b5050505050905090565b60095481565b6112dc61191a565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611340576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806007600061134d61191a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166113fa61191a565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161143f9190613313565b60405180910390a35050565b611456848484611abc565b6114758373ffffffffffffffffffffffffffffffffffffffff166124f5565b156114bd5761148684848484612518565b6114bc576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6114f16119d4565b80600c8190555050565b6060611506826118cc565b61153c576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611546612668565b905060008151036115665760405180602001604052806000815250611591565b80611570846126fa565b60405160200161158192919061413e565b6040516020818303038152906040525b915050919050565b6115a16119d4565b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b600a5481565b600f60009054906101000a900460ff16611622576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161990613f87565b60405180910390fd5b600c5481600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546116709190613fa7565b11156116b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a89061404d565b60405180910390fd5b80600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546116fc9190613fa7565b600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506117488161285a565b50565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6117e76119d4565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611856576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161184d906141d4565b60405180910390fd5b61185f816121fb565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6000816118d7611ab7565b111580156118e6575060005482105b8015611913575060046000838152602001908152602001600020600001601c9054906101000a900460ff16155b9050919050565b600033905090565b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6119dc61191a565b73ffffffffffffffffffffffffffffffffffffffff166119fa61116e565b73ffffffffffffffffffffffffffffffffffffffff1614611a50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4790614240565b60405180910390fd5b565b600a54611a5d610bf6565b82611a689190613fa7565b1115611aa9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aa0906142d2565b60405180910390fd5b611ab382826129f1565b5050565b600090565b6000611ac782611f70565b90508373ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1614611b32576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16611b5361191a565b73ffffffffffffffffffffffffffffffffffffffff161480611b825750611b8185611b7c61191a565b61174b565b5b80611bc75750611b9061191a565b73ffffffffffffffffffffffffffffffffffffffff16611baf84610a14565b73ffffffffffffffffffffffffffffffffffffffff16145b905080611c00576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611c66576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c738585856001612ccb565b611c7f60008487611922565b6001600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160392506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000600460008581526020019081526020016000209050848160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550428160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006001850190506000600460008381526020019081526020016000209050600073ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603611efe576000548214611efd57878160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084602001518160000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b5b505050828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611f698585856001612da1565b5050505050565b611f7861321c565b600082905080611f86611ab7565b116121c4576000548110156121c3576000600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff161515151581525050905080604001516121c157600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146120a55780925050506121f6565b5b6001156121c057818060019003925050600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815260200160008201601c9054906101000a900460ff1615151515815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff16146121bb5780925050506121f6565b6120a6565b5b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6122db828260405180602001604052806000815250612da7565b5050565b600080336040516020016122f3919061433a565b60405160208183030381529060405280519060200120905061231883600e5483613167565b915050919050565b600c5481111580156123325750600081115b612371576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612368906143c7565b60405180910390fd5b600b548161237d610bf6565b6123879190613fa7565b11156123c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123bf90614433565b60405180910390fd5b6000806123db6123d661191a565b610e52565b146123e75760006123ea565b60015b60ff16905080826123fb9190614453565b6009546124089190614487565b34101561244a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244190614515565b60405180910390fd5b61245b61245561191a565b83611a52565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cc240c016124a161191a565b846040518363ffffffff1660e01b81526004016124bf9291906140d9565b600060405180830381600087803b1580156124d957600080fd5b505af11580156124ed573d6000803e3d6000fd5b505050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261253e61191a565b8786866040518563ffffffff1660e01b8152600401612560949392919061458a565b6020604051808303816000875af192505050801561259c57506040513d601f19601f8201168201806040525081019061259991906145eb565b60015b612615573d80600081146125cc576040519150601f19603f3d011682016040523d82523d6000602084013e6125d1565b606091505b50600081510361260d576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60606010805461267790613bbe565b80601f01602080910402602001604051908101604052809291908181526020018280546126a390613bbe565b80156126f05780601f106126c5576101008083540402835291602001916126f0565b820191906000526020600020905b8154815290600101906020018083116126d357829003601f168201915b5050505050905090565b606060008203612741576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612855565b600082905060005b6000821461277357808061275c90613ef3565b915050600a8261276c9190614647565b9150612749565b60008167ffffffffffffffff81111561278f5761278e613797565b5b6040519080825280601f01601f1916602001820160405280156127c15781602001600182028036833780820191505090505b5090505b6000851461284e576001826127da9190614453565b9150600a856127e99190614678565b60306127f59190613fa7565b60f81b81838151811061280b5761280a613e95565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856128479190614647565b94506127c5565b8093505050505b919050565b600c54811115801561286c5750600081115b6128ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128a2906143c7565b60405180910390fd5b600a54816128b7610bf6565b6128c19190613fa7565b1115612902576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128f9906146f5565b60405180910390fd5b600954341015612947576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161293e90614515565b60405180910390fd5b61295861295261191a565b82611a52565b601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cc240c0161299e61191a565b836040518363ffffffff1660e01b81526004016129bc9291906140d9565b600060405180830381600087803b1580156129d657600080fd5b505af11580156129ea573d6000803e3d6000fd5b5050505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612a5d576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008203612a97576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612aa46000848385612ccb565b81600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555081600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550826004600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426004600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506000819050600083820190505b818060010192508573ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808210612c4757816000819055505050612cc66000848385612da1565b505050565b612cd78484848461317e565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612d9b57601160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d230af3a85856040518363ffffffff1660e01b8152600401612d68929190613e6c565b600060405180830381600087803b158015612d8257600080fd5b505af1158015612d96573d6000803e3d6000fd5b505050505b50505050565b50505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612e13576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008303612e4d576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e5a6000858386612ccb565b82600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160008282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555082600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160088282829054906101000a900467ffffffffffffffff160192506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550836004600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550426004600083815260200190815260200160002060000160146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060008190506000848201905061301b8673ffffffffffffffffffffffffffffffffffffffff166124f5565b156130e0575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46130906000878480600101955087612518565b6130c6576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082106130215782600054146130db57600080fd5b61314b565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082106130e1575b8160008190555050506131616000858386612da1565b50505050565b6000826131748584613184565b1490509392505050565b50505050565b60008082905060005b84518110156131cf576131ba828683815181106131ad576131ac613e95565b5b60200260200101516131da565b915080806131c790613ef3565b91505061318d565b508091505092915050565b60008183106131f2576131ed8284613205565b6131fd565b6131fc8383613205565b5b905092915050565b600082600052816020526040600020905092915050565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff1681526020016000151581525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6132a881613273565b81146132b357600080fd5b50565b6000813590506132c58161329f565b92915050565b6000602082840312156132e1576132e0613269565b5b60006132ef848285016132b6565b91505092915050565b60008115159050919050565b61330d816132f8565b82525050565b60006020820190506133286000830184613304565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561336857808201518184015260208101905061334d565b60008484015250505050565b6000601f19601f8301169050919050565b60006133908261332e565b61339a8185613339565b93506133aa81856020860161334a565b6133b381613374565b840191505092915050565b600060208201905081810360008301526133d88184613385565b905092915050565b6000819050919050565b6133f3816133e0565b81146133fe57600080fd5b50565b600081359050613410816133ea565b92915050565b60006020828403121561342c5761342b613269565b5b600061343a84828501613401565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061346e82613443565b9050919050565b61347e81613463565b82525050565b60006020820190506134996000830184613475565b92915050565b6134a881613463565b81146134b357600080fd5b50565b6000813590506134c58161349f565b92915050565b600080604083850312156134e2576134e1613269565b5b60006134f0858286016134b6565b925050602061350185828601613401565b9150509250929050565b60006020828403121561352157613520613269565b5b600061352f848285016134b6565b91505092915050565b613541816133e0565b82525050565b600060208201905061355c6000830184613538565b92915050565b60008060006060848603121561357b5761357a613269565b5b6000613589868287016134b6565b935050602061359a868287016134b6565b92505060406135ab86828701613401565b9150509250925092565b6000819050919050565b6135c8816135b5565b82525050565b60006020820190506135e360008301846135bf565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261360e5761360d6135e9565b5b8235905067ffffffffffffffff81111561362b5761362a6135ee565b5b602083019150836001820283011115613647576136466135f3565b5b9250929050565b6000806020838503121561366557613664613269565b5b600083013567ffffffffffffffff8111156136835761368261326e565b5b61368f858286016135f8565b92509250509250929050565b60008083601f8401126136b1576136b06135e9565b5b8235905067ffffffffffffffff8111156136ce576136cd6135ee565b5b6020830191508360208202830111156136ea576136e96135f3565b5b9250929050565b6000806020838503121561370857613707613269565b5b600083013567ffffffffffffffff8111156137265761372561326e565b5b6137328582860161369b565b92509250509250929050565b613747816135b5565b811461375257600080fd5b50565b6000813590506137648161373e565b92915050565b6000602082840312156137805761377f613269565b5b600061378e84828501613755565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6137cf82613374565b810181811067ffffffffffffffff821117156137ee576137ed613797565b5b80604052505050565b600061380161325f565b905061380d82826137c6565b919050565b600067ffffffffffffffff82111561382d5761382c613797565b5b602082029050602081019050919050565b600061385161384c84613812565b6137f7565b90508083825260208201905060208402830185811115613874576138736135f3565b5b835b8181101561389d57806138898882613755565b845260208401935050602081019050613876565b5050509392505050565b600082601f8301126138bc576138bb6135e9565b5b81356138cc84826020860161383e565b91505092915050565b600080604083850312156138ec576138eb613269565b5b60006138fa85828601613401565b925050602083013567ffffffffffffffff81111561391b5761391a61326e565b5b613927858286016138a7565b9150509250929050565b61393a816132f8565b811461394557600080fd5b50565b60008135905061395781613931565b92915050565b6000806040838503121561397457613973613269565b5b6000613982858286016134b6565b925050602061399385828601613948565b9150509250929050565b600080fd5b600067ffffffffffffffff8211156139bd576139bc613797565b5b6139c682613374565b9050602081019050919050565b82818337600083830152505050565b60006139f56139f0846139a2565b6137f7565b905082815260208101848484011115613a1157613a1061399d565b5b613a1c8482856139d3565b509392505050565b600082601f830112613a3957613a386135e9565b5b8135613a498482602086016139e2565b91505092915050565b60008060008060808587031215613a6c57613a6b613269565b5b6000613a7a878288016134b6565b9450506020613a8b878288016134b6565b9350506040613a9c87828801613401565b925050606085013567ffffffffffffffff811115613abd57613abc61326e565b5b613ac987828801613a24565b91505092959194509250565b6000819050919050565b6000613afa613af5613af084613443565b613ad5565b613443565b9050919050565b6000613b0c82613adf565b9050919050565b6000613b1e82613b01565b9050919050565b613b2e81613b13565b82525050565b6000602082019050613b496000830184613b25565b92915050565b60008060408385031215613b6657613b65613269565b5b6000613b74858286016134b6565b9250506020613b85858286016134b6565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613bd657607f821691505b602082108103613be957613be8613b8f565b5b50919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302613c5c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613c1f565b613c668683613c1f565b95508019841693508086168417925050509392505050565b6000613c99613c94613c8f846133e0565b613ad5565b6133e0565b9050919050565b6000819050919050565b613cb383613c7e565b613cc7613cbf82613ca0565b848454613c2c565b825550505050565b600090565b613cdc613ccf565b613ce7818484613caa565b505050565b5b81811015613d0b57613d00600082613cd4565b600181019050613ced565b5050565b601f821115613d5057613d2181613bfa565b613d2a84613c0f565b81016020851015613d39578190505b613d4d613d4585613c0f565b830182613cec565b50505b505050565b600082821c905092915050565b6000613d7360001984600802613d55565b1980831691505092915050565b6000613d8c8383613d62565b9150826002028217905092915050565b613da68383613bef565b67ffffffffffffffff811115613dbf57613dbe613797565b5b613dc98254613bbe565b613dd4828285613d0f565b6000601f831160018114613e035760008415613df1578287013590505b613dfb8582613d80565b865550613e63565b601f198416613e1186613bfa565b60005b82811015613e3957848901358255600182019150602085019450602081019050613e14565b86831015613e565784890135613e52601f891682613d62565b8355505b6001600288020188555050505b50505050505050565b6000604082019050613e816000830185613475565b613e8e6020830184613475565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613efe826133e0565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613f3057613f2f613ec4565b5b600182019050919050565b7f73746f726520636c6f7365640000000000000000000000000000000000000000600082015250565b6000613f71600c83613339565b9150613f7c82613f3b565b602082019050919050565b60006020820190508181036000830152613fa081613f64565b9050919050565b6000613fb2826133e0565b9150613fbd836133e0565b9250828201905080821115613fd557613fd4613ec4565b5b92915050565b7f4578636565646564206d617820617661696c61626c6520746f2070757263686160008201527f7365000000000000000000000000000000000000000000000000000000000000602082015250565b6000614037602283613339565b915061404282613fdb565b604082019050919050565b600060208201905081810360008301526140668161402a565b9050919050565b7f61646472657373206e6f7420696e2077686974656c6973740000000000000000600082015250565b60006140a3601883613339565b91506140ae8261406d565b602082019050919050565b600060208201905081810360008301526140d281614096565b9050919050565b60006040820190506140ee6000830185613475565b6140fb6020830184613538565b9392505050565b600081905092915050565b60006141188261332e565b6141228185614102565b935061413281856020860161334a565b80840191505092915050565b600061414a828561410d565b9150614156828461410d565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006141be602683613339565b91506141c982614162565b604082019050919050565b600060208201905081810360008301526141ed816141b1565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061422a602083613339565b9150614235826141f4565b602082019050919050565b600060208201905081810360008301526142598161421d565b9050919050565b7f535550504c593a2056616c7565206578636565647320746f74616c537570706c60008201527f7900000000000000000000000000000000000000000000000000000000000000602082015250565b60006142bc602183613339565b91506142c782614260565b604082019050919050565b600060208201905081810360008301526142eb816142af565b9050919050565b60008160601b9050919050565b600061430a826142f2565b9050919050565b600061431c826142ff565b9050919050565b61433461432f82613463565b614311565b82525050565b60006143468284614323565b60148201915081905092915050565b7f5452414e53414354494f4e3a20717479206f66206d696e7473206e6f7420616c60008201527f6f77656400000000000000000000000000000000000000000000000000000000602082015250565b60006143b1602483613339565b91506143bc82614355565b604082019050919050565b600060208201905081810360008301526143e0816143a4565b9050919050565b7f72656163686564206d617820737570706c79206f662070726553616c65000000600082015250565b600061441d601d83613339565b9150614428826143e7565b602082019050919050565b6000602082019050818103600083015261444c81614410565b9050919050565b600061445e826133e0565b9150614469836133e0565b925082820390508181111561448157614480613ec4565b5b92915050565b6000614492826133e0565b915061449d836133e0565b92508282026144ab816133e0565b915082820484148315176144c2576144c1613ec4565b5b5092915050565b7f5041594d454e543a20696e76616c69642076616c756500000000000000000000600082015250565b60006144ff601683613339565b915061450a826144c9565b602082019050919050565b6000602082019050818103600083015261452e816144f2565b9050919050565b600081519050919050565b600082825260208201905092915050565b600061455c82614535565b6145668185614540565b935061457681856020860161334a565b61457f81613374565b840191505092915050565b600060808201905061459f6000830187613475565b6145ac6020830186613475565b6145b96040830185613538565b81810360608301526145cb8184614551565b905095945050505050565b6000815190506145e58161329f565b92915050565b60006020828403121561460157614600613269565b5b600061460f848285016145d6565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614652826133e0565b915061465d836133e0565b92508261466d5761466c614618565b5b828204905092915050565b6000614683826133e0565b915061468e836133e0565b92508261469e5761469d614618565b5b828206905092915050565b7f72656163686564206d617820737570706c790000000000000000000000000000600082015250565b60006146df601283613339565b91506146ea826146a9565b602082019050919050565b6000602082019050818103600083015261470e816146d2565b905091905056fea26469706673582212202da309b6afc79deb6f3f12b61de6fd4e92e1c21ed68d5f743372f53fbf05671764736f6c63430008110033

Deployed Bytecode Sourcemap

57209:4449:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13937:305;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17052:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18556:204;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18118:372;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58642:91;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58319:107;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;13177:312;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19421:170;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57399:50;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57458:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57998:104;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57798:89;;;;;;;;;;;;;:::i;:::-;;60556:111;;;;;;;;;;;;;:::i;:::-;;19662:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;61069:139;;;;;;;;;;;;;:::i;:::-;;57331:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16860:125;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58214:97;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;14306:206;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56033:103;;;;;;;;;;;;;:::i;:::-;;60886:175;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57369:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58110:92;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58741:443;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55385:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61216:102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57899:87;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;17221:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57259:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18832:287;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;19918:370;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57615:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58438:83;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;17396:318;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57710:80;;;;;;;;;;;;;:::i;:::-;;57296:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59196:349;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;19190:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56291:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;13937:305;14039:4;14091:25;14076:40;;;:11;:40;;;;:105;;;;14148:33;14133:48;;;:11;:48;;;;14076:105;:158;;;;14198:36;14222:11;14198:23;:36::i;:::-;14076:158;14056:178;;13937:305;;;:::o;17052:100::-;17106:13;17139:5;17132:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17052:100;:::o;18556:204::-;18624:7;18649:16;18657:7;18649;:16::i;:::-;18644:64;;18674:34;;;;;;;;;;;;;;18644:64;18728:15;:24;18744:7;18728:24;;;;;;;;;;;;;;;;;;;;;18721:31;;18556:204;;;:::o;18118:372::-;18191:13;18207:24;18223:7;18207:15;:24::i;:::-;18191:40;;18252:5;18246:11;;:2;:11;;;18242:48;;18266:24;;;;;;;;;;;;;;18242:48;18323:5;18307:21;;:12;:10;:12::i;:::-;:21;;;18303:139;;18334:37;18351:5;18358:12;:10;:12::i;:::-;18334:16;:37::i;:::-;18330:112;;18395:35;;;;;;;;;;;;;;18330:112;18303:139;18454:28;18463:2;18467:7;18476:5;18454:8;:28::i;:::-;18180:310;18118:372;;:::o;58642:91::-;55271:13;:11;:13::i;:::-;58709:16:::1;58717:2;58721:3;58709:7;:16::i;:::-;58642:91:::0;;:::o;58319:107::-;55271:13;:11;:13::i;:::-;58408:9:::1;58386;;:32;;;;;;;;;;;;;;;;;;58319:107:::0;:::o;13177:312::-;13230:7;13455:15;:13;:15::i;:::-;13440:12;;13424:13;;:28;:46;13417:53;;13177:312;:::o;19421:170::-;19555:28;19565:4;19571:2;19575:7;19555:9;:28::i;:::-;19421:170;;;:::o;57399:50::-;;;;;;;;;;;;;;;;;:::o;57458:25::-;;;;:::o;57998:104::-;55271:13;:11;:13::i;:::-;58090:4:::1;;58075:12;:19;;;;;;;:::i;:::-;;57998:104:::0;;:::o;57798:89::-;55271:13;:11;:13::i;:::-;57868:11:::1;;;;;;;;;;;57867:12;57853:11;;:26;;;;;;;;;;;;;;;;;;57798:89::o:0;60556:111::-;55271:13;:11;:13::i;:::-;60614:12:::1;:10;:12::i;:::-;60606:30;;:53;60637:21;60606:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;60556:111::o:0;19662:185::-;19800:39;19817:4;19823:2;19827:7;19800:39;;;;;;;;;;;;:16;:39::i;:::-;19662:185;;;:::o;61069:139::-;61112:9;;;;;;;;;;;:22;;;61135:10;61155:1;61112:46;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61169:9;;;;;;;;;;;:19;;;61189:10;61169:31;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61069:139::o;57331:31::-;;;;:::o;16860:125::-;16924:7;16951:21;16964:7;16951:12;:21::i;:::-;:26;;;16944:33;;16860:125;;;:::o;58214:97::-;55271:13;:11;:13::i;:::-;58294:9:::1;58282;:21;;;;58214:97:::0;:::o;14306:206::-;14370:7;14411:1;14394:19;;:5;:19;;;14390:60;;14422:28;;;;;;;;;;;;;;14390:60;14476:12;:19;14489:5;14476:19;;;;;;;;;;;;;;;:27;;;;;;;;;;;;14468:36;;14461:43;;14306:206;;;:::o;56033:103::-;55271:13;:11;:13::i;:::-;56098:30:::1;56125:1;56098:18;:30::i;:::-;56033:103::o:0;60886:175::-;55271:13;:11;:13::i;:::-;60965:9:::1;60960:94;60984:6;;:13;;60980:1;:17;60960:94;;;61019:23;61029:6;;61036:1;61029:9;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;61040:1;61019:9;:23::i;:::-;60999:3;;;;;:::i;:::-;;;;60960:94;;;;60886:175:::0;;:::o;57369:21::-;;;;:::o;58110:92::-;55271:13;:11;:13::i;:::-;58190:4:::1;58177:10;:17;;;;58110:92:::0;:::o;58741:443::-;58827:11;;;;;;;;;;;58819:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;58925:5;;58918:3;58888:15;:27;58904:10;58888:27;;;;;;;;;;;;;;;;:33;;;;:::i;:::-;:42;;58866:126;;;;;;;;;;;;:::i;:::-;;;;;;;;;59089:3;59046:15;:27;59062:10;59046:27;;;;;;;;;;;;;;;;:46;;;;:::i;:::-;59003:15;:27;59019:10;59003:27;;;;;;;;;;;;;;;:89;;;;59111:13;59118:5;59111:6;:13::i;:::-;59103:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;59164:12;59172:3;59164:7;:12::i;:::-;58741:443;;:::o;55385:87::-;55431:7;55458:6;;;;;;;;;;;55451:13;;55385:87;:::o;61216:102::-;61274:9;;;;;;;;;;;:15;;;61290:10;61302:7;61274:36;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61216:102;:::o;57899:87::-;55271:13;:11;:13::i;:::-;57970:8:::1;57962:5;:16;;;;57899:87:::0;:::o;17221:104::-;17277:13;17310:7;17303:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17221:104;:::o;57259:30::-;;;;:::o;18832:287::-;18943:12;:10;:12::i;:::-;18931:24;;:8;:24;;;18927:54;;18964:17;;;;;;;;;;;;;;18927:54;19039:8;18994:18;:32;19013:12;:10;:12::i;:::-;18994:32;;;;;;;;;;;;;;;:42;19027:8;18994:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;19092:8;19063:48;;19078:12;:10;:12::i;:::-;19063:48;;;19102:8;19063:48;;;;;;:::i;:::-;;;;;;;;18832:287;;:::o;19918:370::-;20085:28;20095:4;20101:2;20105:7;20085:9;:28::i;:::-;20128:15;:2;:13;;;:15::i;:::-;20124:157;;;20149:56;20180:4;20186:2;20190:7;20199:5;20149:30;:56::i;:::-;20145:136;;20229:40;;;;;;;;;;;;;;20145:136;20124:157;19918:370;;;;:::o;57615:26::-;;;;;;;;;;;;;:::o;58438:83::-;55271:13;:11;:13::i;:::-;58507:6:::1;58499:5;:14;;;;58438:83:::0;:::o;17396:318::-;17469:13;17500:16;17508:7;17500;:16::i;:::-;17495:59;;17525:29;;;;;;;;;;;;;;17495:59;17567:21;17591:10;:8;:10::i;:::-;17567:34;;17644:1;17625:7;17619:21;:26;:87;;;;;;;;;;;;;;;;;17672:7;17681:18;:7;:16;:18::i;:::-;17655:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;17619:87;17612:94;;;17396:318;;;:::o;57710:80::-;55271:13;:11;:13::i;:::-;57774:8:::1;;;;;;;;;;;57773:9;57762:8;;:20;;;;;;;;;;;;;;;;;;57710:80::o:0;57296:28::-;;;;:::o;59196:349::-;59255:8;;;;;;;;;;;59247:33;;;;;;;;;;;;:::i;:::-;;;;;;;;;59350:5;;59343:3;59313:15;:27;59329:10;59313:27;;;;;;;;;;;;;;;;:33;;;;:::i;:::-;:42;;59291:126;;;;;;;;;;;;:::i;:::-;;;;;;;;;59514:3;59471:15;:27;59487:10;59471:27;;;;;;;;;;;;;;;;:46;;;;:::i;:::-;59428:15;:27;59444:10;59428:27;;;;;;;;;;;;;;;:89;;;;59528:9;59533:3;59528:4;:9::i;:::-;59196:349;:::o;19190:164::-;19287:4;19311:18;:25;19330:5;19311:25;;;;;;;;;;;;;;;:35;19337:8;19311:35;;;;;;;;;;;;;;;;;;;;;;;;;19304:42;;19190:164;;;;:::o;56291:201::-;55271:13;:11;:13::i;:::-;56400:1:::1;56380:22;;:8;:22;;::::0;56372:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;56456:28;56475:8;56456:18;:28::i;:::-;56291:201:::0;:::o;10978:157::-;11063:4;11102:25;11087:40;;;:11;:40;;;;11080:47;;10978:157;;;:::o;20543:174::-;20600:4;20643:7;20624:15;:13;:15::i;:::-;:26;;:53;;;;;20664:13;;20654:7;:23;20624:53;:85;;;;;20682:11;:20;20694:7;20682:20;;;;;;;;;;;:27;;;;;;;;;;;;20681:28;20624:85;20617:92;;20543:174;;;:::o;9966:98::-;10019:7;10046:10;10039:17;;9966:98;:::o;29765:196::-;29907:2;29880:15;:24;29896:7;29880:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;29945:7;29941:2;29925:28;;29934:5;29925:28;;;;;;;;;;;;29765:196;;;:::o;55550:132::-;55625:12;:10;:12::i;:::-;55614:23;;:7;:5;:7::i;:::-;:23;;;55606:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;55550:132::o;60374:170::-;60464:9;;60447:13;:11;:13::i;:::-;60441:3;:19;;;;:::i;:::-;:32;;60433:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;60522:14;60528:2;60532:3;60522:5;:14::i;:::-;60374:170;;:::o;12951:92::-;13007:7;12951:92;:::o;24713:2130::-;24828:35;24866:21;24879:7;24866:12;:21::i;:::-;24828:59;;24926:4;24904:26;;:13;:18;;;:26;;;24900:67;;24939:28;;;;;;;;;;;;;;24900:67;24980:22;25022:4;25006:20;;:12;:10;:12::i;:::-;:20;;;:73;;;;25043:36;25060:4;25066:12;:10;:12::i;:::-;25043:16;:36::i;:::-;25006:73;:126;;;;25120:12;:10;:12::i;:::-;25096:36;;:20;25108:7;25096:11;:20::i;:::-;:36;;;25006:126;24980:153;;25151:17;25146:66;;25177:35;;;;;;;;;;;;;;25146:66;25241:1;25227:16;;:2;:16;;;25223:52;;25252:23;;;;;;;;;;;;;;25223:52;25288:43;25310:4;25316:2;25320:7;25329:1;25288:21;:43::i;:::-;25396:35;25413:1;25417:7;25426:4;25396:8;:35::i;:::-;25757:1;25727:12;:18;25740:4;25727:18;;;;;;;;;;;;;;;:26;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25801:1;25773:12;:16;25786:2;25773:16;;;;;;;;;;;;;;;:24;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25819:31;25853:11;:20;25865:7;25853:20;;;;;;;;;;;25819:54;;25904:2;25888:8;:13;;;:18;;;;;;;;;;;;;;;;;;25954:15;25921:8;:23;;;:49;;;;;;;;;;;;;;;;;;26222:19;26254:1;26244:7;:11;26222:33;;26270:31;26304:11;:24;26316:11;26304:24;;;;;;;;;;;26270:58;;26372:1;26347:27;;:8;:13;;;;;;;;;;;;:27;;;26343:384;;26557:13;;26542:11;:28;26538:174;;26611:4;26595:8;:13;;;:20;;;;;;;;;;;;;;;;;;26664:13;:28;;;26638:8;:23;;;:54;;;;;;;;;;;;;;;;;;26538:174;26343:384;25702:1036;;;26774:7;26770:2;26755:27;;26764:4;26755:27;;;;;;;;;;;;26793:42;26814:4;26820:2;26824:7;26833:1;26793:20;:42::i;:::-;24817:2026;;24713:2130;;;:::o;15687:1111::-;15749:21;;:::i;:::-;15783:12;15798:7;15783:22;;15866:4;15847:15;:13;:15::i;:::-;:23;15843:888;;15883:13;;15876:4;:20;15872:859;;;15917:31;15951:11;:17;15963:4;15951:17;;;;;;;;;;;15917:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15992:9;:16;;;15987:729;;16063:1;16037:28;;:9;:14;;;:28;;;16033:101;;16101:9;16094:16;;;;;;16033:101;16436:261;16443:4;16436:261;;;16476:6;;;;;;;;16521:11;:17;16533:4;16521:17;;;;;;;;;;;16509:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16595:1;16569:28;;:9;:14;;;:28;;;16565:109;;16637:9;16630:16;;;;;;16565:109;16436:261;;;15987:729;15898:833;15872:859;15843:888;16759:31;;;;;;;;;;;;;;15687:1111;;;;:::o;56652:191::-;56726:16;56745:6;;;;;;;;;;;56726:25;;56771:8;56762:6;;:17;;;;;;;;;;;;;;;;;;56826:8;56795:40;;56816:8;56795:40;;;;;;;;;;;;56715:128;56652:191;:::o;20801:104::-;20870:27;20880:2;20884:8;20870:27;;;;;;;;;;;;:9;:27::i;:::-;20801:104;;:::o;60675:203::-;60738:4;60755:12;60797:10;60780:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;60770:39;;;;;;60755:54;;60827:43;60846:5;60853:10;;60865:4;60827:18;:43::i;:::-;60820:50;;;60675:203;;;:::o;59918:448::-;59980:5;;59973:3;:12;;:23;;;;;59995:1;59989:3;:7;59973:23;59965:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;60079:12;;60072:3;60056:13;:11;:13::i;:::-;:19;;;;:::i;:::-;:35;;60048:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;60136:9;60175:1;60148:23;60158:12;:10;:12::i;:::-;60148:9;:23::i;:::-;:28;:36;;60183:1;60148:36;;;60179:1;60148:36;60136:48;;;;60231:4;60225:3;:10;;;;:::i;:::-;60216:5;;:20;;;;:::i;:::-;60203:9;:33;;60195:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;60274:26;60282:12;:10;:12::i;:::-;60296:3;60274:7;:26::i;:::-;60311:9;;;;;;;;;;;:28;;;60340:12;:10;:12::i;:::-;60354:3;60311:47;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59954:412;59918:448;:::o;37354:326::-;37414:4;37671:1;37649:7;:19;;;:23;37642:30;;37354:326;;;:::o;30453:667::-;30616:4;30653:2;30637:36;;;30674:12;:10;:12::i;:::-;30688:4;30694:7;30703:5;30637:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;30633:480;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30888:1;30871:6;:13;:18;30867:235;;30917:40;;;;;;;;;;;;;;30867:235;31060:6;31054:13;31045:6;31041:2;31037:15;31030:38;30633:480;30766:45;;;30756:55;;;:6;:55;;;;30749:62;;;30453:667;;;;;;:::o;58529:105::-;58581:13;58614:12;58607:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58529:105;:::o;34112:723::-;34168:13;34398:1;34389:5;:10;34385:53;;34416:10;;;;;;;;;;;;;;;;;;;;;34385:53;34448:12;34463:5;34448:20;;34479:14;34504:78;34519:1;34511:4;:9;34504:78;;34537:8;;;;;:::i;:::-;;;;34568:2;34560:10;;;;;:::i;:::-;;;34504:78;;;34592:19;34624:6;34614:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34592:39;;34642:154;34658:1;34649:5;:10;34642:154;;34686:1;34676:11;;;;;:::i;:::-;;;34753:2;34745:5;:10;;;;:::i;:::-;34732:2;:24;;;;:::i;:::-;34719:39;;34702:6;34709;34702:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;34782:2;34773:11;;;;;:::i;:::-;;;34642:154;;;34820:6;34806:21;;;;;34112:723;;;;:::o;59553:357::-;59612:5;;59605:3;:12;;:23;;;;;59627:1;59621:3;:7;59605:23;59597:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;59711:9;;59704:3;59688:13;:11;:13::i;:::-;:19;;;;:::i;:::-;:32;;59680:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;59775:5;;59762:9;:18;;59754:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;59818:26;59826:12;:10;:12::i;:::-;59840:3;59818:7;:26::i;:::-;59855:9;;;;;;;;;;;:28;;;59884:12;:10;:12::i;:::-;59898:3;59855:47;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59553:357;:::o;23286:1173::-;23351:20;23374:13;;23351:36;;23416:1;23402:16;;:2;:16;;;23398:48;;23427:19;;;;;;;;;;;;;;23398:48;23473:1;23461:8;:13;23457:44;;23483:18;;;;;;;;;;;;;;23457:44;23514:61;23544:1;23548:2;23552:12;23566:8;23514:21;:61::i;:::-;23887:8;23852:12;:16;23865:2;23852:16;;;;;;;;;;;;;;;:24;;;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23951:8;23911:12;:16;23924:2;23911:16;;;;;;;;;;;;;;;:29;;;:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24010:2;23977:11;:25;23989:12;23977:25;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;24077:15;24027:11;:25;24039:12;24027:25;;;;;;;;;;;:40;;;:66;;;;;;;;;;;;;;;;;;24110:20;24133:12;24110:35;;24160:11;24189:8;24174:12;:23;24160:37;;24214:111;24266:14;;;;;;24262:2;24241:40;;24258:1;24241:40;;;;;;;;;;;;24320:3;24305:12;:18;24214:111;;24357:12;24341:13;:28;;;;23827:554;;24391:60;24420:1;24424:2;24428:12;24442:8;24391:20;:60::i;:::-;23340:1119;23286:1173;;:::o;61326:329::-;61498:56;61526:4;61532:2;61536:7;61545:8;61498:27;:56::i;:::-;61585:1;61569:18;;:4;:18;;;61565:83;;61604:9;;;;;;;;;;;:22;;;61627:4;61633:2;61604:32;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61565:83;61326:329;;;;:::o;32586:158::-;;;;;:::o;21278:1749::-;21401:20;21424:13;;21401:36;;21466:1;21452:16;;:2;:16;;;21448:48;;21477:19;;;;;;;;;;;;;;21448:48;21523:1;21511:8;:13;21507:44;;21533:18;;;;;;;;;;;;;;21507:44;21564:61;21594:1;21598:2;21602:12;21616:8;21564:21;:61::i;:::-;21937:8;21902:12;:16;21915:2;21902:16;;;;;;;;;;;;;;;:24;;;:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22001:8;21961:12;:16;21974:2;21961:16;;;;;;;;;;;;;;;:29;;;:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22060:2;22027:11;:25;22039:12;22027:25;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;22127:15;22077:11;:25;22089:12;22077:25;;;;;;;;;;;:40;;;:66;;;;;;;;;;;;;;;;;;22160:20;22183:12;22160:35;;22210:11;22239:8;22224:12;:23;22210:37;;22268:15;:2;:13;;;:15::i;:::-;22264:631;;;22304:313;22360:12;22356:2;22335:38;;22352:1;22335:38;;;;;;;;;;;;22401:69;22440:1;22444:2;22448:14;;;;;;22464:5;22401:30;:69::i;:::-;22396:174;;22506:40;;;;;;;;;;;;;;22396:174;22612:3;22597:12;:18;22304:313;;22698:12;22681:13;;:29;22677:43;;22712:8;;;22677:43;22264:631;;;22761:119;22817:14;;;;;;22813:2;22792:40;;22809:1;22792:40;;;;;;;;;;;;22875:3;22860:12;:18;22761:119;;22264:631;22925:12;22909:13;:28;;;;21877:1072;;22959:60;22988:1;22992:2;22996:12;23010:8;22959:20;:60::i;:::-;21390:1637;21278:1749;;;:::o;46697:190::-;46822:4;46875;46846:25;46859:5;46866:4;46846:12;:25::i;:::-;:33;46839:40;;46697:190;;;;;:::o;31768:159::-;;;;;:::o;47564:296::-;47647:7;47667:20;47690:4;47667:27;;47710:9;47705:118;47729:5;:12;47725:1;:16;47705:118;;;47778:33;47788:12;47802:5;47808:1;47802:8;;;;;;;;:::i;:::-;;;;;;;;47778:9;:33::i;:::-;47763:48;;47743:3;;;;;:::i;:::-;;;;47705:118;;;;47840:12;47833:19;;;47564:296;;;;:::o;53771:149::-;53834:7;53865:1;53861;:5;:51;;53892:20;53907:1;53910;53892:14;:20::i;:::-;53861:51;;;53869:20;53884:1;53887;53869:14;:20::i;:::-;53861:51;53854:58;;53771:149;;;;:::o;53928:268::-;53996:13;54103:1;54097:4;54090:15;54132:1;54126:4;54119:15;54173:4;54167;54157:21;54148:30;;53928:268;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:329::-;4949:6;4998:2;4986:9;4977:7;4973:23;4969:32;4966:119;;;5004:79;;:::i;:::-;4966:119;5124:1;5149:53;5194:7;5185:6;5174:9;5170:22;5149:53;:::i;:::-;5139:63;;5095:117;4890:329;;;;:::o;5225:118::-;5312:24;5330:5;5312:24;:::i;:::-;5307:3;5300:37;5225:118;;:::o;5349:222::-;5442:4;5480:2;5469:9;5465:18;5457:26;;5493:71;5561:1;5550:9;5546:17;5537:6;5493:71;:::i;:::-;5349:222;;;;:::o;5577:619::-;5654:6;5662;5670;5719:2;5707:9;5698:7;5694:23;5690:32;5687:119;;;5725:79;;:::i;:::-;5687:119;5845:1;5870:53;5915:7;5906:6;5895:9;5891:22;5870:53;:::i;:::-;5860:63;;5816:117;5972:2;5998:53;6043:7;6034:6;6023:9;6019:22;5998:53;:::i;:::-;5988:63;;5943:118;6100:2;6126:53;6171:7;6162:6;6151:9;6147:22;6126:53;:::i;:::-;6116:63;;6071:118;5577:619;;;;;:::o;6202:77::-;6239:7;6268:5;6257:16;;6202:77;;;:::o;6285:118::-;6372:24;6390:5;6372:24;:::i;:::-;6367:3;6360:37;6285:118;;:::o;6409:222::-;6502:4;6540:2;6529:9;6525:18;6517:26;;6553:71;6621:1;6610:9;6606:17;6597:6;6553:71;:::i;:::-;6409:222;;;;:::o;6637:117::-;6746:1;6743;6736:12;6760:117;6869:1;6866;6859:12;6883:117;6992:1;6989;6982:12;7020:553;7078:8;7088:6;7138:3;7131:4;7123:6;7119:17;7115:27;7105:122;;7146:79;;:::i;:::-;7105:122;7259:6;7246:20;7236:30;;7289:18;7281:6;7278:30;7275:117;;;7311:79;;:::i;:::-;7275:117;7425:4;7417:6;7413:17;7401:29;;7479:3;7471:4;7463:6;7459:17;7449:8;7445:32;7442:41;7439:128;;;7486:79;;:::i;:::-;7439:128;7020:553;;;;;:::o;7579:529::-;7650:6;7658;7707:2;7695:9;7686:7;7682:23;7678:32;7675:119;;;7713:79;;:::i;:::-;7675:119;7861:1;7850:9;7846:17;7833:31;7891:18;7883:6;7880:30;7877:117;;;7913:79;;:::i;:::-;7877:117;8026:65;8083:7;8074:6;8063:9;8059:22;8026:65;:::i;:::-;8008:83;;;;7804:297;7579:529;;;;;:::o;8131:568::-;8204:8;8214:6;8264:3;8257:4;8249:6;8245:17;8241:27;8231:122;;8272:79;;:::i;:::-;8231:122;8385:6;8372:20;8362:30;;8415:18;8407:6;8404:30;8401:117;;;8437:79;;:::i;:::-;8401:117;8551:4;8543:6;8539:17;8527:29;;8605:3;8597:4;8589:6;8585:17;8575:8;8571:32;8568:41;8565:128;;;8612:79;;:::i;:::-;8565:128;8131:568;;;;;:::o;8705:559::-;8791:6;8799;8848:2;8836:9;8827:7;8823:23;8819:32;8816:119;;;8854:79;;:::i;:::-;8816:119;9002:1;8991:9;8987:17;8974:31;9032:18;9024:6;9021:30;9018:117;;;9054:79;;:::i;:::-;9018:117;9167:80;9239:7;9230:6;9219:9;9215:22;9167:80;:::i;:::-;9149:98;;;;8945:312;8705:559;;;;;:::o;9270:122::-;9343:24;9361:5;9343:24;:::i;:::-;9336:5;9333:35;9323:63;;9382:1;9379;9372:12;9323:63;9270:122;:::o;9398:139::-;9444:5;9482:6;9469:20;9460:29;;9498:33;9525:5;9498:33;:::i;:::-;9398:139;;;;:::o;9543:329::-;9602:6;9651:2;9639:9;9630:7;9626:23;9622:32;9619:119;;;9657:79;;:::i;:::-;9619:119;9777:1;9802:53;9847:7;9838:6;9827:9;9823:22;9802:53;:::i;:::-;9792:63;;9748:117;9543:329;;;;:::o;9878:180::-;9926:77;9923:1;9916:88;10023:4;10020:1;10013:15;10047:4;10044:1;10037:15;10064:281;10147:27;10169:4;10147:27;:::i;:::-;10139:6;10135:40;10277:6;10265:10;10262:22;10241:18;10229:10;10226:34;10223:62;10220:88;;;10288:18;;:::i;:::-;10220:88;10328:10;10324:2;10317:22;10107:238;10064:281;;:::o;10351:129::-;10385:6;10412:20;;:::i;:::-;10402:30;;10441:33;10469:4;10461:6;10441:33;:::i;:::-;10351:129;;;:::o;10486:311::-;10563:4;10653:18;10645:6;10642:30;10639:56;;;10675:18;;:::i;:::-;10639:56;10725:4;10717:6;10713:17;10705:25;;10785:4;10779;10775:15;10767:23;;10486:311;;;:::o;10820:710::-;10916:5;10941:81;10957:64;11014:6;10957:64;:::i;:::-;10941:81;:::i;:::-;10932:90;;11042:5;11071:6;11064:5;11057:21;11105:4;11098:5;11094:16;11087:23;;11158:4;11150:6;11146:17;11138:6;11134:30;11187:3;11179:6;11176:15;11173:122;;;11206:79;;:::i;:::-;11173:122;11321:6;11304:220;11338:6;11333:3;11330:15;11304:220;;;11413:3;11442:37;11475:3;11463:10;11442:37;:::i;:::-;11437:3;11430:50;11509:4;11504:3;11500:14;11493:21;;11380:144;11364:4;11359:3;11355:14;11348:21;;11304:220;;;11308:21;10922:608;;10820:710;;;;;:::o;11553:370::-;11624:5;11673:3;11666:4;11658:6;11654:17;11650:27;11640:122;;11681:79;;:::i;:::-;11640:122;11798:6;11785:20;11823:94;11913:3;11905:6;11898:4;11890:6;11886:17;11823:94;:::i;:::-;11814:103;;11630:293;11553:370;;;;:::o;11929:684::-;12022:6;12030;12079:2;12067:9;12058:7;12054:23;12050:32;12047:119;;;12085:79;;:::i;:::-;12047:119;12205:1;12230:53;12275:7;12266:6;12255:9;12251:22;12230:53;:::i;:::-;12220:63;;12176:117;12360:2;12349:9;12345:18;12332:32;12391:18;12383:6;12380:30;12377:117;;;12413:79;;:::i;:::-;12377:117;12518:78;12588:7;12579:6;12568:9;12564:22;12518:78;:::i;:::-;12508:88;;12303:303;11929:684;;;;;:::o;12619:116::-;12689:21;12704:5;12689:21;:::i;:::-;12682:5;12679:32;12669:60;;12725:1;12722;12715:12;12669:60;12619:116;:::o;12741:133::-;12784:5;12822:6;12809:20;12800:29;;12838:30;12862:5;12838:30;:::i;:::-;12741:133;;;;:::o;12880:468::-;12945:6;12953;13002:2;12990:9;12981:7;12977:23;12973:32;12970:119;;;13008:79;;:::i;:::-;12970:119;13128:1;13153:53;13198:7;13189:6;13178:9;13174:22;13153:53;:::i;:::-;13143:63;;13099:117;13255:2;13281:50;13323:7;13314:6;13303:9;13299:22;13281:50;:::i;:::-;13271:60;;13226:115;12880:468;;;;;:::o;13354:117::-;13463:1;13460;13453:12;13477:307;13538:4;13628:18;13620:6;13617:30;13614:56;;;13650:18;;:::i;:::-;13614:56;13688:29;13710:6;13688:29;:::i;:::-;13680:37;;13772:4;13766;13762:15;13754:23;;13477:307;;;:::o;13790:146::-;13887:6;13882:3;13877;13864:30;13928:1;13919:6;13914:3;13910:16;13903:27;13790:146;;;:::o;13942:423::-;14019:5;14044:65;14060:48;14101:6;14060:48;:::i;:::-;14044:65;:::i;:::-;14035:74;;14132:6;14125:5;14118:21;14170:4;14163:5;14159:16;14208:3;14199:6;14194:3;14190:16;14187:25;14184:112;;;14215:79;;:::i;:::-;14184:112;14305:54;14352:6;14347:3;14342;14305:54;:::i;:::-;14025:340;13942:423;;;;;:::o;14384:338::-;14439:5;14488:3;14481:4;14473:6;14469:17;14465:27;14455:122;;14496:79;;:::i;:::-;14455:122;14613:6;14600:20;14638:78;14712:3;14704:6;14697:4;14689:6;14685:17;14638:78;:::i;:::-;14629:87;;14445:277;14384:338;;;;:::o;14728:943::-;14823:6;14831;14839;14847;14896:3;14884:9;14875:7;14871:23;14867:33;14864:120;;;14903:79;;:::i;:::-;14864:120;15023:1;15048:53;15093:7;15084:6;15073:9;15069:22;15048:53;:::i;:::-;15038:63;;14994:117;15150:2;15176:53;15221:7;15212:6;15201:9;15197:22;15176:53;:::i;:::-;15166:63;;15121:118;15278:2;15304:53;15349:7;15340:6;15329:9;15325:22;15304:53;:::i;:::-;15294:63;;15249:118;15434:2;15423:9;15419:18;15406:32;15465:18;15457:6;15454:30;15451:117;;;15487:79;;:::i;:::-;15451:117;15592:62;15646:7;15637:6;15626:9;15622:22;15592:62;:::i;:::-;15582:72;;15377:287;14728:943;;;;;;;:::o;15677:60::-;15705:3;15726:5;15719:12;;15677:60;;;:::o;15743:142::-;15793:9;15826:53;15844:34;15853:24;15871:5;15853:24;:::i;:::-;15844:34;:::i;:::-;15826:53;:::i;:::-;15813:66;;15743:142;;;:::o;15891:126::-;15941:9;15974:37;16005:5;15974:37;:::i;:::-;15961:50;;15891:126;;;:::o;16023:144::-;16091:9;16124:37;16155:5;16124:37;:::i;:::-;16111:50;;16023:144;;;:::o;16173:167::-;16278:55;16327:5;16278:55;:::i;:::-;16273:3;16266:68;16173:167;;:::o;16346:258::-;16457:4;16495:2;16484:9;16480:18;16472:26;;16508:89;16594:1;16583:9;16579:17;16570:6;16508:89;:::i;:::-;16346:258;;;;:::o;16610:474::-;16678:6;16686;16735:2;16723:9;16714:7;16710:23;16706:32;16703:119;;;16741:79;;:::i;:::-;16703:119;16861:1;16886:53;16931:7;16922:6;16911:9;16907:22;16886:53;:::i;:::-;16876:63;;16832:117;16988:2;17014:53;17059:7;17050:6;17039:9;17035:22;17014:53;:::i;:::-;17004:63;;16959:118;16610:474;;;;;:::o;17090:180::-;17138:77;17135:1;17128:88;17235:4;17232:1;17225:15;17259:4;17256:1;17249:15;17276:320;17320:6;17357:1;17351:4;17347:12;17337:22;;17404:1;17398:4;17394:12;17425:18;17415:81;;17481:4;17473:6;17469:17;17459:27;;17415:81;17543:2;17535:6;17532:14;17512:18;17509:38;17506:84;;17562:18;;:::i;:::-;17506:84;17327:269;17276:320;;;:::o;17602:97::-;17661:6;17689:3;17679:13;;17602:97;;;;:::o;17705:141::-;17754:4;17777:3;17769:11;;17800:3;17797:1;17790:14;17834:4;17831:1;17821:18;17813:26;;17705:141;;;:::o;17852:93::-;17889:6;17936:2;17931;17924:5;17920:14;17916:23;17906:33;;17852:93;;;:::o;17951:107::-;17995:8;18045:5;18039:4;18035:16;18014:37;;17951:107;;;;:::o;18064:393::-;18133:6;18183:1;18171:10;18167:18;18206:97;18236:66;18225:9;18206:97;:::i;:::-;18324:39;18354:8;18343:9;18324:39;:::i;:::-;18312:51;;18396:4;18392:9;18385:5;18381:21;18372:30;;18445:4;18435:8;18431:19;18424:5;18421:30;18411:40;;18140:317;;18064:393;;;;;:::o;18463:142::-;18513:9;18546:53;18564:34;18573:24;18591:5;18573:24;:::i;:::-;18564:34;:::i;:::-;18546:53;:::i;:::-;18533:66;;18463:142;;;:::o;18611:75::-;18654:3;18675:5;18668:12;;18611:75;;;:::o;18692:269::-;18802:39;18833:7;18802:39;:::i;:::-;18863:91;18912:41;18936:16;18912:41;:::i;:::-;18904:6;18897:4;18891:11;18863:91;:::i;:::-;18857:4;18850:105;18768:193;18692:269;;;:::o;18967:73::-;19012:3;18967:73;:::o;19046:189::-;19123:32;;:::i;:::-;19164:65;19222:6;19214;19208:4;19164:65;:::i;:::-;19099:136;19046:189;;:::o;19241:186::-;19301:120;19318:3;19311:5;19308:14;19301:120;;;19372:39;19409:1;19402:5;19372:39;:::i;:::-;19345:1;19338:5;19334:13;19325:22;;19301:120;;;19241:186;;:::o;19433:543::-;19534:2;19529:3;19526:11;19523:446;;;19568:38;19600:5;19568:38;:::i;:::-;19652:29;19670:10;19652:29;:::i;:::-;19642:8;19638:44;19835:2;19823:10;19820:18;19817:49;;;19856:8;19841:23;;19817:49;19879:80;19935:22;19953:3;19935:22;:::i;:::-;19925:8;19921:37;19908:11;19879:80;:::i;:::-;19538:431;;19523:446;19433:543;;;:::o;19982:117::-;20036:8;20086:5;20080:4;20076:16;20055:37;;19982:117;;;;:::o;20105:169::-;20149:6;20182:51;20230:1;20226:6;20218:5;20215:1;20211:13;20182:51;:::i;:::-;20178:56;20263:4;20257;20253:15;20243:25;;20156:118;20105:169;;;;:::o;20279:295::-;20355:4;20501:29;20526:3;20520:4;20501:29;:::i;:::-;20493:37;;20563:3;20560:1;20556:11;20550:4;20547:21;20539:29;;20279:295;;;;:::o;20579:1403::-;20703:44;20743:3;20738;20703:44;:::i;:::-;20812:18;20804:6;20801:30;20798:56;;;20834:18;;:::i;:::-;20798:56;20878:38;20910:4;20904:11;20878:38;:::i;:::-;20963:67;21023:6;21015;21009:4;20963:67;:::i;:::-;21057:1;21086:2;21078:6;21075:14;21103:1;21098:632;;;;21774:1;21791:6;21788:84;;;21847:9;21842:3;21838:19;21825:33;21816:42;;21788:84;21898:67;21958:6;21951:5;21898:67;:::i;:::-;21892:4;21885:81;21747:229;21068:908;;21098:632;21150:4;21146:9;21138:6;21134:22;21184:37;21216:4;21184:37;:::i;:::-;21243:1;21257:215;21271:7;21268:1;21265:14;21257:215;;;21357:9;21352:3;21348:19;21335:33;21327:6;21320:49;21408:1;21400:6;21396:14;21386:24;;21455:2;21444:9;21440:18;21427:31;;21294:4;21291:1;21287:12;21282:17;;21257:215;;;21500:6;21491:7;21488:19;21485:186;;;21565:9;21560:3;21556:19;21543:33;21608:48;21650:4;21642:6;21638:17;21627:9;21608:48;:::i;:::-;21600:6;21593:64;21508:163;21485:186;21717:1;21713;21705:6;21701:14;21697:22;21691:4;21684:36;21105:625;;;21068:908;;20678:1304;;;20579:1403;;;:::o;21988:332::-;22109:4;22147:2;22136:9;22132:18;22124:26;;22160:71;22228:1;22217:9;22213:17;22204:6;22160:71;:::i;:::-;22241:72;22309:2;22298:9;22294:18;22285:6;22241:72;:::i;:::-;21988:332;;;;;:::o;22326:180::-;22374:77;22371:1;22364:88;22471:4;22468:1;22461:15;22495:4;22492:1;22485:15;22512:180;22560:77;22557:1;22550:88;22657:4;22654:1;22647:15;22681:4;22678:1;22671:15;22698:233;22737:3;22760:24;22778:5;22760:24;:::i;:::-;22751:33;;22806:66;22799:5;22796:77;22793:103;;22876:18;;:::i;:::-;22793:103;22923:1;22916:5;22912:13;22905:20;;22698:233;;;:::o;22937:162::-;23077:14;23073:1;23065:6;23061:14;23054:38;22937:162;:::o;23105:366::-;23247:3;23268:67;23332:2;23327:3;23268:67;:::i;:::-;23261:74;;23344:93;23433:3;23344:93;:::i;:::-;23462:2;23457:3;23453:12;23446:19;;23105:366;;;:::o;23477:419::-;23643:4;23681:2;23670:9;23666:18;23658:26;;23730:9;23724:4;23720:20;23716:1;23705:9;23701:17;23694:47;23758:131;23884:4;23758:131;:::i;:::-;23750:139;;23477:419;;;:::o;23902:191::-;23942:3;23961:20;23979:1;23961:20;:::i;:::-;23956:25;;23995:20;24013:1;23995:20;:::i;:::-;23990:25;;24038:1;24035;24031:9;24024:16;;24059:3;24056:1;24053:10;24050:36;;;24066:18;;:::i;:::-;24050:36;23902:191;;;;:::o;24099:221::-;24239:34;24235:1;24227:6;24223:14;24216:58;24308:4;24303:2;24295:6;24291:15;24284:29;24099:221;:::o;24326:366::-;24468:3;24489:67;24553:2;24548:3;24489:67;:::i;:::-;24482:74;;24565:93;24654:3;24565:93;:::i;:::-;24683:2;24678:3;24674:12;24667:19;;24326:366;;;:::o;24698:419::-;24864:4;24902:2;24891:9;24887:18;24879:26;;24951:9;24945:4;24941:20;24937:1;24926:9;24922:17;24915:47;24979:131;25105:4;24979:131;:::i;:::-;24971:139;;24698:419;;;:::o;25123:174::-;25263:26;25259:1;25251:6;25247:14;25240:50;25123:174;:::o;25303:366::-;25445:3;25466:67;25530:2;25525:3;25466:67;:::i;:::-;25459:74;;25542:93;25631:3;25542:93;:::i;:::-;25660:2;25655:3;25651:12;25644:19;;25303:366;;;:::o;25675:419::-;25841:4;25879:2;25868:9;25864:18;25856:26;;25928:9;25922:4;25918:20;25914:1;25903:9;25899:17;25892:47;25956:131;26082:4;25956:131;:::i;:::-;25948:139;;25675:419;;;:::o;26100:332::-;26221:4;26259:2;26248:9;26244:18;26236:26;;26272:71;26340:1;26329:9;26325:17;26316:6;26272:71;:::i;:::-;26353:72;26421:2;26410:9;26406:18;26397:6;26353:72;:::i;:::-;26100:332;;;;;:::o;26438:148::-;26540:11;26577:3;26562:18;;26438:148;;;;:::o;26592:390::-;26698:3;26726:39;26759:5;26726:39;:::i;:::-;26781:89;26863:6;26858:3;26781:89;:::i;:::-;26774:96;;26879:65;26937:6;26932:3;26925:4;26918:5;26914:16;26879:65;:::i;:::-;26969:6;26964:3;26960:16;26953:23;;26702:280;26592:390;;;;:::o;26988:435::-;27168:3;27190:95;27281:3;27272:6;27190:95;:::i;:::-;27183:102;;27302:95;27393:3;27384:6;27302:95;:::i;:::-;27295:102;;27414:3;27407:10;;26988:435;;;;;:::o;27429:225::-;27569:34;27565:1;27557:6;27553:14;27546:58;27638:8;27633:2;27625:6;27621:15;27614:33;27429:225;:::o;27660:366::-;27802:3;27823:67;27887:2;27882:3;27823:67;:::i;:::-;27816:74;;27899:93;27988:3;27899:93;:::i;:::-;28017:2;28012:3;28008:12;28001:19;;27660:366;;;:::o;28032:419::-;28198:4;28236:2;28225:9;28221:18;28213:26;;28285:9;28279:4;28275:20;28271:1;28260:9;28256:17;28249:47;28313:131;28439:4;28313:131;:::i;:::-;28305:139;;28032:419;;;:::o;28457:182::-;28597:34;28593:1;28585:6;28581:14;28574:58;28457:182;:::o;28645:366::-;28787:3;28808:67;28872:2;28867:3;28808:67;:::i;:::-;28801:74;;28884:93;28973:3;28884:93;:::i;:::-;29002:2;28997:3;28993:12;28986:19;;28645:366;;;:::o;29017:419::-;29183:4;29221:2;29210:9;29206:18;29198:26;;29270:9;29264:4;29260:20;29256:1;29245:9;29241:17;29234:47;29298:131;29424:4;29298:131;:::i;:::-;29290:139;;29017:419;;;:::o;29442:220::-;29582:34;29578:1;29570:6;29566:14;29559:58;29651:3;29646:2;29638:6;29634:15;29627:28;29442:220;:::o;29668:366::-;29810:3;29831:67;29895:2;29890:3;29831:67;:::i;:::-;29824:74;;29907:93;29996:3;29907:93;:::i;:::-;30025:2;30020:3;30016:12;30009:19;;29668:366;;;:::o;30040:419::-;30206:4;30244:2;30233:9;30229:18;30221:26;;30293:9;30287:4;30283:20;30279:1;30268:9;30264:17;30257:47;30321:131;30447:4;30321:131;:::i;:::-;30313:139;;30040:419;;;:::o;30465:94::-;30498:8;30546:5;30542:2;30538:14;30517:35;;30465:94;;;:::o;30565:::-;30604:7;30633:20;30647:5;30633:20;:::i;:::-;30622:31;;30565:94;;;:::o;30665:100::-;30704:7;30733:26;30753:5;30733:26;:::i;:::-;30722:37;;30665:100;;;:::o;30771:157::-;30876:45;30896:24;30914:5;30896:24;:::i;:::-;30876:45;:::i;:::-;30871:3;30864:58;30771:157;;:::o;30934:256::-;31046:3;31061:75;31132:3;31123:6;31061:75;:::i;:::-;31161:2;31156:3;31152:12;31145:19;;31181:3;31174:10;;30934:256;;;;:::o;31196:223::-;31336:34;31332:1;31324:6;31320:14;31313:58;31405:6;31400:2;31392:6;31388:15;31381:31;31196:223;:::o;31425:366::-;31567:3;31588:67;31652:2;31647:3;31588:67;:::i;:::-;31581:74;;31664:93;31753:3;31664:93;:::i;:::-;31782:2;31777:3;31773:12;31766:19;;31425:366;;;:::o;31797:419::-;31963:4;32001:2;31990:9;31986:18;31978:26;;32050:9;32044:4;32040:20;32036:1;32025:9;32021:17;32014:47;32078:131;32204:4;32078:131;:::i;:::-;32070:139;;31797:419;;;:::o;32222:179::-;32362:31;32358:1;32350:6;32346:14;32339:55;32222:179;:::o;32407:366::-;32549:3;32570:67;32634:2;32629:3;32570:67;:::i;:::-;32563:74;;32646:93;32735:3;32646:93;:::i;:::-;32764:2;32759:3;32755:12;32748:19;;32407:366;;;:::o;32779:419::-;32945:4;32983:2;32972:9;32968:18;32960:26;;33032:9;33026:4;33022:20;33018:1;33007:9;33003:17;32996:47;33060:131;33186:4;33060:131;:::i;:::-;33052:139;;32779:419;;;:::o;33204:194::-;33244:4;33264:20;33282:1;33264:20;:::i;:::-;33259:25;;33298:20;33316:1;33298:20;:::i;:::-;33293:25;;33342:1;33339;33335:9;33327:17;;33366:1;33360:4;33357:11;33354:37;;;33371:18;;:::i;:::-;33354:37;33204:194;;;;:::o;33404:410::-;33444:7;33467:20;33485:1;33467:20;:::i;:::-;33462:25;;33501:20;33519:1;33501:20;:::i;:::-;33496:25;;33556:1;33553;33549:9;33578:30;33596:11;33578:30;:::i;:::-;33567:41;;33757:1;33748:7;33744:15;33741:1;33738:22;33718:1;33711:9;33691:83;33668:139;;33787:18;;:::i;:::-;33668:139;33452:362;33404:410;;;;:::o;33820:172::-;33960:24;33956:1;33948:6;33944:14;33937:48;33820:172;:::o;33998:366::-;34140:3;34161:67;34225:2;34220:3;34161:67;:::i;:::-;34154:74;;34237:93;34326:3;34237:93;:::i;:::-;34355:2;34350:3;34346:12;34339:19;;33998:366;;;:::o;34370:419::-;34536:4;34574:2;34563:9;34559:18;34551:26;;34623:9;34617:4;34613:20;34609:1;34598:9;34594:17;34587:47;34651:131;34777:4;34651:131;:::i;:::-;34643:139;;34370:419;;;:::o;34795:98::-;34846:6;34880:5;34874:12;34864:22;;34795:98;;;:::o;34899:168::-;34982:11;35016:6;35011:3;35004:19;35056:4;35051:3;35047:14;35032:29;;34899:168;;;;:::o;35073:373::-;35159:3;35187:38;35219:5;35187:38;:::i;:::-;35241:70;35304:6;35299:3;35241:70;:::i;:::-;35234:77;;35320:65;35378:6;35373:3;35366:4;35359:5;35355:16;35320:65;:::i;:::-;35410:29;35432:6;35410:29;:::i;:::-;35405:3;35401:39;35394:46;;35163:283;35073:373;;;;:::o;35452:640::-;35647:4;35685:3;35674:9;35670:19;35662:27;;35699:71;35767:1;35756:9;35752:17;35743:6;35699:71;:::i;:::-;35780:72;35848:2;35837:9;35833:18;35824:6;35780:72;:::i;:::-;35862;35930:2;35919:9;35915:18;35906:6;35862:72;:::i;:::-;35981:9;35975:4;35971:20;35966:2;35955:9;35951:18;35944:48;36009:76;36080:4;36071:6;36009:76;:::i;:::-;36001:84;;35452:640;;;;;;;:::o;36098:141::-;36154:5;36185:6;36179:13;36170:22;;36201:32;36227:5;36201:32;:::i;:::-;36098:141;;;;:::o;36245:349::-;36314:6;36363:2;36351:9;36342:7;36338:23;36334:32;36331:119;;;36369:79;;:::i;:::-;36331:119;36489:1;36514:63;36569:7;36560:6;36549:9;36545:22;36514:63;:::i;:::-;36504:73;;36460:127;36245:349;;;;:::o;36600:180::-;36648:77;36645:1;36638:88;36745:4;36742:1;36735:15;36769:4;36766:1;36759:15;36786:185;36826:1;36843:20;36861:1;36843:20;:::i;:::-;36838:25;;36877:20;36895:1;36877:20;:::i;:::-;36872:25;;36916:1;36906:35;;36921:18;;:::i;:::-;36906:35;36963:1;36960;36956:9;36951:14;;36786:185;;;;:::o;36977:176::-;37009:1;37026:20;37044:1;37026:20;:::i;:::-;37021:25;;37060:20;37078:1;37060:20;:::i;:::-;37055:25;;37099:1;37089:35;;37104:18;;:::i;:::-;37089:35;37145:1;37142;37138:9;37133:14;;36977:176;;;;:::o;37159:168::-;37299:20;37295:1;37287:6;37283:14;37276:44;37159:168;:::o;37333:366::-;37475:3;37496:67;37560:2;37555:3;37496:67;:::i;:::-;37489:74;;37572:93;37661:3;37572:93;:::i;:::-;37690:2;37685:3;37681:12;37674:19;;37333:366;;;:::o;37705:419::-;37871:4;37909:2;37898:9;37894:18;37886:26;;37958:9;37952:4;37948:20;37944:1;37933:9;37929:17;37922:47;37986:131;38112:4;37986:131;:::i;:::-;37978:139;;37705:419;;;:::o

Swarm Source

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