ETH Price: $3,400.16 (+1.97%)

Token

Super Ice Cream Party (ICECREAM)
 

Overview

Max Total Supply

10,000 ICECREAM

Holders

608

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
bkturtle.eth
Balance
10 ICECREAM
0x2df181cfc9756035dcb91d9f4e7c9f92f4ffa32c
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:
SuperIceCreamParty

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

// File: erc721a/contracts/IERC721A.sol


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

pragma solidity ^0.8.4;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    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;
        // Arbitrary data similar to `startTimestamp` that can be set through `_extraData`.
        uint24 extraData;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId` (inclusive) is transferred from `from` to `to`,
     * as defined in the ERC2309 standard. See `_mintERC2309` for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}

// File: erc721a/contracts/ERC721A.sol


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

pragma solidity ^0.8.4;


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        return _tokenApprovals[tokenId];
    }

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

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

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

    /**
     * @dev See {IERC721-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 {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

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

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

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

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

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _mint(address to, uint256 quantity) internal {
        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` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);

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

            uint256 tokenId = startTokenId;
            uint256 end = startTokenId + quantity;
            do {
                emit Transfer(address(0), to, tokenId++);
            } while (tokenId < end);

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

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

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

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

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

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

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

    /**
     * @dev Returns the storage slot and value for the approved address of `tokenId`.
     */
    function _getApprovedAddress(uint256 tokenId)
        private
        view
        returns (uint256 approvedAddressSlot, address approvedAddress)
    {
        mapping(uint256 => address) storage tokenApprovalsPtr = _tokenApprovals;
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId]`.
        assembly {
            // Compute the slot.
            mstore(0x00, tokenId)
            mstore(0x20, tokenApprovalsPtr.slot)
            approvedAddressSlot := keccak256(0x00, 0x40)
            // Load the slot's value from storage.
            approvedAddress := sload(approvedAddressSlot)
        }
    }

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

    /**
     * @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 transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

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

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

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

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

        _beforeTokenTransfers(from, to, tokenId, 1);

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

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

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

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

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

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

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

        address from = address(uint160(prevOwnershipPacked));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

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

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


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

pragma solidity ^0.8.0;

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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


// OpenZeppelin Contracts v4.4.1 (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 `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

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


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;


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

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


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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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


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

pragma solidity ^0.8.0;








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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        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 virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

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

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

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

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

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

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

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

// File: contracts/SuperIceCreamParty.sol


pragma solidity ^0.8.0;




/*
lloooddxxxkkkkkkkkkkkOOOOOO00000000KKXXXKKKXNXKXK0KKK0KXXK00000000000000OOkkkOOkkkxxxxxxxxxxdddoooll
ooodxxxxxxkkkkkkkkkOOO0KKK00KKKXXXXKXXXXXXXNNXXNXXXXXXXNNXXXKKKKKKKKKXXXK000000OOOkkkkkkxxxxxddddooo
ooddxxxxxxkkkkOOOOOOO0KXNNXXNXXNNNNXXNNNNNNNNNNNNNNNNXNNNNNNXXXXXXXXNNNNXXKKK00000OOOOOOOkkxxddddddd
ddddxxxkkkkkkOO00OO00KKXNNNNNNNNNNNNNNWWNNNNNNWWWWWWNNNNNNNNNNNNXXNNNNNNNNNXKKXXKK0O000OOOkxxxxddddd
ddddxxxkkOO0OO00KKKKXXXXNNWNNWWWWWWWNNWWWWWWNXOdlloox0NWWWWWNNNNNNNNNNNNNNNXXNXXXKKKKK0OOOkkxxxxxddd
dxxxxxkkOO00KKKKKXNNNNNNNWWWWWWWWWWWWWWWWWWWO;.      .;dKWWWWWWWWWWWWWNWNNNNNNXXXXXXXKK0OOOOkkxxxxxx
dxxxxkkkOO00KXXXXXNNNNWWWWWWWWWWWWWWWWWWWWWNo..dkc..    'xXWWWWWWWWWWWWWWNNNNNNNNNNNXXXKKKK0Okxxxxxx
xxxxkkkOOO00KXNNNNNNWWWWWWWWWWWWWWWWWWWWWWWWXdd0Oc..      :0WWWWWWWWWWWWWWWWNNWNNNNNNNNNNXK0Okkkkxxx
xxkkkOO000KKXXNNNNNWWWWWWWWWWWWWWWWWWWWWN0kdc;'..          ,OWWWWWWWWWWWWWWWWWWWWWWWWWNNNXXKKK00Okxx
kkkkOOO0KKKXXNNNNNWWWWWWWWWWWWWWWWWWWW0o'.                  ,0WWWWWWWWWWWWWWWWWWWWWWWWNNNNNNXXKOkkxx
xkkkOO0KXXXXXNNNNNWWWWWWWWWWWWWWWWWWWO'                      lXWWWWWWWWWWWWWWWWWWWWWWWWWWNNNXK0Okkxx
kkkOOO0KKXNNNNNNNWWWWWWWWWWWWWWWWWWMNc                        'o0WWWWWWWWWWWWWWWWWWWWWWWWNNX0OOkkkkx
OO0000KKKXNNNWWWWWWWWWWWWWWWWWWWWMMMNl                          .dNWWWWWWWWWWWWWWWWWWWWWNNXXKK0OOkkx
OO00KXXXXNNNWWWWWWWWWWWWWWWWWWWMMMMWNx.                          .oNWWWWWWWWWWWWWWWWWWWNNNNNXXK0OOkk
OOO0KXNNNNNWWWWWWWWWWWWWWWWWWWMMMNOc,.                            '0MWWWWWWWWWWWWWWWWWWNNNNNXKK0OOkk
OO00KXNNNWWWWWWWWWWWWWWWWWWWWMMMKc.                               .OMMMWWWWWWWWWWWWWWWWWWNNXKKK00OOk
OO0KKXXNNNWWWWWWWWWWWWWWWMMMMMMNl                                 :XMMMMWWWWWWWWWWWWWWWWWWNNXXXK00OO
000KKXNNNWWWWWWWWWWWWWWWMMMMMMMK,                                 lXMMMMMWWWWWWWWWWWWWWWWWNNNXXK00OO
KKKXXNNWWWWWWWWWWWWWWWWWMMMMMMMX:                                  ;0WMMMMMWWWWWWWWWWWWWWWNNNNXXKK0O
0KKXNNNWWWWWWWWWWWWWWWWWMMMMMMMWO,              .;clddo:.           :XMMMMMMWWWWWWWWWWWWWWWWNNNNNXXK
KKXXNNWWWWWWWWWWWWWWWWMMMMMMMMMMNx.           ,xKWMWKKNWXl.         .OMMMMMMWWWWWWWWWWWWWWWWWWWNNNNX
0KXNNWWWWWWWWWWWWWWWWWMMMMMMMMW0c.          .xNMXxc;..cXMK;         ;KMMMMMMMWWWWWWWWWWWWWWWWWNNNNNX
KKXNNWWWWWWWWWWWWWWWWMMMMMMMMM0,           ,OWW0;     :XMX;        ;OWMMMMMMMWWWWWWWWWWWWWWWWWWNNNNX
XXNNNWWWWWWWWWWWWWWWWMMMMMMMMNl           'OMM0'     :KMWd.        :KWMMMMMMMMWWWWWWWWWWWWWWWWWWNNXX
XNNWWWWWWWWWWWWWWWWWWMMMMMMMMN:           lNMNc    .dNMNo.          'OWMMMMMMWWWWWWWWWWWWWWWWWWWNNNX
XXNNWWWWWWWWWWWWWWWWWMMMMMMMMWo           .dKO, .cx0WW0:             lNMMMMMMWWWWWWWWWWWWWWWWWWNNNXX
XNNWWWWWWWWWWWWWWWWWWWMMMMMMMMXc            .. ,kNMWKl.             ,0WMMMMMMWWWWWWWWWWWWWWWWWNNXXKK
XXNNNWWWWWWWWWWWWWWWWWMMMMMMMMM0;             cKMNKd'              ,OMMMMMMMMWWWWWWWWWWWWWWWWWWNNXK0
XNNNNWWWWWWWWWWWWWWWWWWMMMMMMMMW0,           cXWO;.               'OWMMMMMMMMWWWWWWWWWWWWWWWWWWNXXKK
KXNNNNNWWWWWWWWWWWWWWWWWMMMMMMMMX:          .kMO'                 ;KMMMMMMMMWWWWWWWWWWWWWWWWWNNNXKK0
O0KXXNNNNWWWWWWWWWWWWWWWWMMMMMMMNc          .lXk.                 :XMMMMMMMWWWWWWWWWWWWWWWWWWNNXXKKK
OO0KKXXNNNWWWWWWWWWWWWWWWWMMMMMMWo           .:c.                 lNMMMMMMMWWWWWWWWWWWWWWWWNNNXKK000
OO00KXXXNNWWWWWWWWWWWWWWWWWMMMMMM0,         ,OXXl                'OMMMMMWWWWWWWWWWWWWWWWWWNNNXXKK0OO
kOO0KKKKXNNWWWWWWWWWWWWWWWWWWMMMMWO'       .dWMWo               .kWMMMWWWWWWWWWWWWWWWWWWWWWNNNXK00OO
kkOO00KXNNNNNWWWWWWWWWWWWWWWWWWMMMWk.       .co:.              .kWMMMWWWWWWWWWWWWWWWWWWWWWNNNNXK0OOO
kkOO0KXXNNNNNWWWWWWWWWWWWWWWWWWMWMMKl.                        .c0WMWWWWWWWWWWWWWWWWWWWWNNNNNXXKK00Ok
xkkOO0KKXXNNWWWWWWWWWWWWWWWWWWWWWWMMWk.                      .xWWWWWWWWWWWWWWWWWWWWWWWWNNNXKKK0000OO
xxkkkOO0KXNWWWWWWWWWWWWWWWWWWWWWWWWWMK,                      ,0MWWWWWWWWWWWWWWWWWWWNNNNNNNXK00OOOkkk
xxxkkOKXNNNWWWWWWWWWWWWWWWWWWWWWWWWWWNc                      :XWWWWWWWWWWWWWWWWWWWNNNNNXXXXXK0OOkkkx
xxkkOKXXNNNNNWWWWWWWWWWWWWWWWWWWWWWWWWx.                    .dWWWWWWWWWWWWWWWWWWWWNNNNNXXKKK00OOkkkk
xxkkO0KKKXNNNNWWWWWWWWWWWWWWWWWWWWWWWWO'                    .kWWWWWWWWWWWWWWWWWWWNNNNNXXKK000OOkkkxx
xxxkkkOO0KXNNNNNNNNNWWWNNWWWWWWWWWWWWWX;                    ;KWWWWWWWWWWWWWWWWWWNNNNNXXK00OOOOkkxxxx
xxxxxxkO0KKKKXXXNNNNNNNNNNNWWWWWWWWWWWNo                    lNWWWWWWWWWWWWWWWWWNNNXXXXXK00OOkkkxxxxd
xxxxxxkkOOOO0KKXXXXXXXNNNNNNNWWWWWWWWWWx.                  .xWWWWWWWWWWWWNNNNNNNNNXKKKKK00OOkkxxxxxd
ddddxxxxkkOOO0KKKKKXXXNXXNNNNNNNNNNNNNW0,                  'OWNNWWWWWWWNNNNNNXXXKKKK000000Okkxxxdddd
dddddxxxxkOOO00000KKKXXKXNNNNNNNNNXXNXX0:                  ;0NNNNNNNNNNNNNNNXKK00OO00OOkkkkkkxxxdddd
dddddddxxkkOOOOOOO00000KKXXNNNNNXXKK0Okkc.                .:kO00KNNNNXXNXXNNXK0OOOOOOOkkkkxxxxxxddoo
oooddddxxxxxkkkkkkOOO00000KKXXXKKKKKOkxxxoc:;;,,,,',,,;;:clxkOO00KXXXKKKK0KKK00OOOkkkkkkkkxxxxxdddoo
llooodddxxxxxxxxxxkkkOOOOOOO000000000OOOOOOO0OkOOkkkOOO00OO00KKKK00000000OOOOOOkkkkkkkkkkxxxxdddoool
:cccllloooooooooooooddddddddxxdxxxxxxxxxxxkkkkxkkxxkkkkOOOkkOOOOkkxxxxxxxxxxxxxdddddddddddooollccccc
*/
contract SuperIceCreamParty is ERC721A, Ownable {

    enum SaleStatus { NONE, PRIVATE, PUBLIC, UNLIMITED }

    string private _baseTokenURI;
    string private _prerevealURI;
    bool private revealed = false;
    uint256 public MAX_TOKENS = 10000;
    uint256 public constant MAX_TOKENS_FOR_TEAM = 100;
    uint256 public constant MAX_TOKENS_PER_PRIVATE_MINT = 20;
    uint256 public constant MAX_TOKENS_PER_PUBLIC_MINT = 20;
    uint256 public privatePrice = 0.000 ether;  // FREE!
    uint256 public publicPrice = 0.000 ether;  // FREE!
    uint256 public unlimitedPrice = 0.001 ether;  // AYCE!
    SaleStatus public saleStatus = SaleStatus.NONE;
    mapping(address => uint) public privateAllowList;
    mapping(address => uint) public privateMintCounts;
    mapping(address => uint) public publicMintCounts;

    constructor() ERC721A("Super Ice Cream Party", "ICECREAM") {
        _prerevealURI = "ipfs://bafybeicp2suolib2uphtn67mkkr5bgsbzydttbknwppmt33pvoxikusp5m";
        reserve();
    }

    modifier tryBlockContract() {
        require(tx.origin == msg.sender, "contracts cannot call this contract");
        _;
    }

    modifier canMint(uint _amount) {
        require(saleStatus != SaleStatus.NONE, "sale is not active");
        require(_amount > 0, "must mint at least one token");
        require(totalSupply() + _amount <= MAX_TOKENS, "minting would exceed max supply");
        _;
    }

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

    function setBaseURI(string calldata base) external onlyOwner {
        _baseTokenURI = base;
    }

    function setPrerevealURI(string calldata base) external onlyOwner {
        _prerevealURI = base;
    }

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory){
        if (!super._exists(tokenId)) revert URIQueryForNonexistentToken();
        if(!revealed) return _prerevealURI;
        return super.tokenURI(tokenId);
    }

    function reveal() external onlyOwner {
        revealed = true;
    }

    function setSaleStatus(SaleStatus targetSaleStatus) external onlyOwner {
        saleStatus = targetSaleStatus;
    }

    function setPrivateAllowList(address[] calldata addresses, uint[] calldata amount) external onlyOwner {
        for (uint256 i = 0; i < addresses.length; i++) {
            require(amount[i] <= MAX_TOKENS_PER_PRIVATE_MINT, "amount would exceed max allowed");
            privateAllowList[addresses[i]] = amount[i];
        }
    }

    // in case of unforseen event
    function removePrivateAllowList(address[] calldata addresses) external onlyOwner {
        for (uint256 i = 0; i < addresses.length; i++) {
            delete privateAllowList[addresses[i]];
        }
    }

    // in case of unforeseen event
    function setPrice(uint _publicPrice, uint _unlimitedPrice) public onlyOwner {
        publicPrice = _publicPrice;
        unlimitedPrice = _unlimitedPrice;
    }

    function reserve() private onlyOwner {
        require(totalSupply() < MAX_TOKENS_FOR_TEAM, "reserve tokens already minted");

        _safeMint(msg.sender, MAX_TOKENS_FOR_TEAM);
    }

    function privateMint(uint _amount) public payable canMint(_amount) tryBlockContract {
        require(saleStatus == SaleStatus.PRIVATE,  "private mint not active");
        uint allowed = privateAllowList[msg.sender];
        require(allowed > 0, "not in allowlist");
        require(_amount <= allowed, "minting exceeds allowlist limit");
        require(privateMintCounts[msg.sender] + _amount <= MAX_TOKENS_PER_PRIVATE_MINT, "minting exceeds address limit of 20");
        require(msg.value == privatePrice * _amount, "etheruem sent incorrect");

        privateAllowList[msg.sender] -= _amount;
        privateMintCounts[msg.sender] += _amount;
        _safeMint(msg.sender, _amount);
    }

    function publicMint(uint _amount) public payable canMint(_amount) tryBlockContract {
        require(saleStatus == SaleStatus.PUBLIC, "public mint not active");
        require(publicMintCounts[msg.sender] + _amount <= MAX_TOKENS_PER_PUBLIC_MINT, "minting exceeds address limit of 20");
        require(msg.value == publicPrice * _amount, "etheruem sent incorrect");

        publicMintCounts[msg.sender] += _amount;
        _safeMint(msg.sender, _amount);
    }

    function unlimitedMint(uint _amount) public payable canMint(_amount) tryBlockContract {
        require(saleStatus == SaleStatus.UNLIMITED, "unlimited mint is not active");
        require(msg.value == unlimitedPrice * _amount, "ethereum sent incorrect");

        _safeMint(msg.sender, _amount);
    }

    function withdraw() external onlyOwner {
        uint256 balance = address(this).balance;
        Address.sendValue(payable(owner()), balance);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS_FOR_TEAM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS_PER_PRIVATE_MINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS_PER_PUBLIC_MINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"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":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"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":[{"internalType":"address","name":"","type":"address"}],"name":"privateAllowList","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"privateMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"privateMintCounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"privatePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"publicMintCounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"removePrivateAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reveal","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":[],"name":"saleStatus","outputs":[{"internalType":"enum SuperIceCreamParty.SaleStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"base","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"base","type":"string"}],"name":"setPrerevealURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_publicPrice","type":"uint256"},{"internalType":"uint256","name":"_unlimitedPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256[]","name":"amount","type":"uint256[]"}],"name":"setPrivateAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum SuperIceCreamParty.SaleStatus","name":"targetSaleStatus","type":"uint8"}],"name":"setSaleStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"unlimitedMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"unlimitedPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000600b60006101000a81548160ff021916908315150217905550612710600c556000600d556000600e5566038d7ea4c68000600f556000601060006101000a81548160ff0219169083600381111562000063576200006262000851565b5b02179055503480156200007557600080fd5b506040518060400160405280601581526020017f53757065722049636520437265616d20506172747900000000000000000000008152506040518060400160405280600881526020017f494345435245414d0000000000000000000000000000000000000000000000008152508160029081620000f3919062000afa565b50806003908162000105919062000afa565b50620001166200017f60201b60201c565b60008190555050506200013e620001326200018460201b60201c565b6200018c60201b60201c565b604051806080016040528060428152602001620054cd60429139600a908162000168919062000afa565b50620001796200025260201b60201c565b62000eae565b600090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620002626200018460201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620002886200034b60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1614620002e1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002d89062000c42565b60405180910390fd5b6064620002f36200037560201b60201c565b1062000336576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200032d9062000cb4565b60405180910390fd5b620003493360646200039460201b60201c565b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000620003876200017f60201b60201c565b6001546000540303905090565b620003b6828260405180602001604052806000815250620003ba60201b60201c565b5050565b620003cc83836200046b60201b60201c565b60008373ffffffffffffffffffffffffffffffffffffffff163b146200046657600080549050600083820390505b6200041560008683806001019450866200066860201b60201c565b6200044c576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110620003fa5781600054146200046357600080fd5b50505b505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603620004d8576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000820362000513576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620005286000848385620007c960201b60201c565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550620005b783620005996000866000620007cf60201b60201c565b620005aa85620007ff60201b60201c565b176200080f60201b60201c565b60046000838152602001908152602001600020819055506000819050600083830190505b818060010192508573ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808210620005db578060008190555050506200066360008483856200083a60201b60201c565b505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02620006966200084060201b60201c565b8786866040518563ffffffff1660e01b8152600401620006ba949392919062000dc6565b6020604051808303816000875af1925050508015620006f957506040513d601f19601f82011682018060405250810190620006f6919062000e7c565b60015b62000776573d80600081146200072c576040519150601f19603f3d011682016040523d82523d6000602084013e62000731565b606091505b5060008151036200076e576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b50505050565b60008060e883901c905060e8620007ee8686846200084860201b60201c565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600033905090565b60009392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200090257607f821691505b602082108103620009185762000917620008ba565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620009827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000943565b6200098e868362000943565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620009db620009d5620009cf84620009a6565b620009b0565b620009a6565b9050919050565b6000819050919050565b620009f783620009ba565b62000a0f62000a0682620009e2565b84845462000950565b825550505050565b600090565b62000a2662000a17565b62000a33818484620009ec565b505050565b5b8181101562000a5b5762000a4f60008262000a1c565b60018101905062000a39565b5050565b601f82111562000aaa5762000a74816200091e565b62000a7f8462000933565b8101602085101562000a8f578190505b62000aa762000a9e8562000933565b83018262000a38565b50505b505050565b600082821c905092915050565b600062000acf6000198460080262000aaf565b1980831691505092915050565b600062000aea838362000abc565b9150826002028217905092915050565b62000b058262000880565b67ffffffffffffffff81111562000b215762000b206200088b565b5b62000b2d8254620008e9565b62000b3a82828562000a5f565b600060209050601f83116001811462000b72576000841562000b5d578287015190505b62000b69858262000adc565b86555062000bd9565b601f19841662000b82866200091e565b60005b8281101562000bac5784890151825560018201915060208501945060208101905062000b85565b8683101562000bcc578489015162000bc8601f89168262000abc565b8355505b6001600288020188555050505b505050505050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600062000c2a60208362000be1565b915062000c378262000bf2565b602082019050919050565b6000602082019050818103600083015262000c5d8162000c1b565b9050919050565b7f7265736572766520746f6b656e7320616c7265616479206d696e746564000000600082015250565b600062000c9c601d8362000be1565b915062000ca98262000c64565b602082019050919050565b6000602082019050818103600083015262000ccf8162000c8d565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000d038262000cd6565b9050919050565b62000d158162000cf6565b82525050565b62000d2681620009a6565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b8381101562000d6857808201518184015260208101905062000d4b565b60008484015250505050565b6000601f19601f8301169050919050565b600062000d928262000d2c565b62000d9e818562000d37565b935062000db081856020860162000d48565b62000dbb8162000d74565b840191505092915050565b600060808201905062000ddd600083018762000d0a565b62000dec602083018662000d0a565b62000dfb604083018562000d1b565b818103606083015262000e0f818462000d85565b905095945050505050565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b62000e568162000e1f565b811462000e6257600080fd5b50565b60008151905062000e768162000e4b565b92915050565b60006020828403121562000e955762000e9462000e1a565b5b600062000ea58482850162000e65565b91505092915050565b61460f8062000ebe6000396000f3fe60806040526004361061022f5760003560e01c806374df85b61161012e578063b0686def116100ab578063e985e9c51161006f578063e985e9c5146107fd578063f2fde38b1461083a578063f47c84c514610863578063f7d975771461088e578063f9020e33146108b75761022f565b8063b0686def1461071a578063b88d4fde14610743578063c5da5cbe1461076c578063c87b56dd14610797578063e373934e146107d45761022f565b8063a22cb465116100f2578063a22cb46514610656578063a475b5dd1461067f578063a945bf8014610696578063aad66a12146106c1578063abfe40a8146106fe5761022f565b806374df85b61461056d578063774ede13146105aa57806387c0568b146105d55780638da5cb5b1461060057806395d89b411461062b5761022f565b80632db11544116101bc5780634891ad88116101805780634891ad881461048a57806355f804b3146104b35780636352211e146104dc57806370a0823114610519578063715018a6146105565761022f565b80632db11544146103d557806339c6da89146103f15780633ccfd60b1461040d57806342842e0e146104245780634346fbc81461044d5761022f565b8063081812fc11610203578063081812fc146102f0578063095ea7b31461032d57806318160ddd1461035657806323b872dd1461038157806328c95017146103aa5761022f565b8062d2cc8e1461023457806301ffc9a71461025f57806306fdde031461029c578063078eef28146102c7575b600080fd5b34801561024057600080fd5b506102496108e2565b6040516102569190612f69565b60405180910390f35b34801561026b57600080fd5b5061028660048036038101906102819190612ff0565b6108e8565b6040516102939190613038565b60405180910390f35b3480156102a857600080fd5b506102b161097a565b6040516102be91906130e3565b60405180910390f35b3480156102d357600080fd5b506102ee60048036038101906102e9919061316a565b610a0c565b005b3480156102fc57600080fd5b50610317600480360381019061031291906131e3565b610a9e565b6040516103249190613251565b60405180910390f35b34801561033957600080fd5b50610354600480360381019061034f9190613298565b610b1a565b005b34801561036257600080fd5b5061036b610c5b565b6040516103789190612f69565b60405180910390f35b34801561038d57600080fd5b506103a860048036038101906103a391906132d8565b610c72565b005b3480156103b657600080fd5b506103bf610f94565b6040516103cc9190612f69565b60405180910390f35b6103ef60048036038101906103ea91906131e3565b610f99565b005b61040b600480360381019061040691906131e3565b6112cf565b005b34801561041957600080fd5b50610422611520565b005b34801561043057600080fd5b5061044b600480360381019061044691906132d8565b6115b5565b005b34801561045957600080fd5b50610474600480360381019061046f919061332b565b6115d5565b6040516104819190612f69565b60405180910390f35b34801561049657600080fd5b506104b160048036038101906104ac919061337d565b6115ed565b005b3480156104bf57600080fd5b506104da60048036038101906104d5919061316a565b611696565b005b3480156104e857600080fd5b5061050360048036038101906104fe91906131e3565b611728565b6040516105109190613251565b60405180910390f35b34801561052557600080fd5b50610540600480360381019061053b919061332b565b61173a565b60405161054d9190612f69565b60405180910390f35b34801561056257600080fd5b5061056b6117f2565b005b34801561057957600080fd5b50610594600480360381019061058f919061332b565b61187a565b6040516105a19190612f69565b60405180910390f35b3480156105b657600080fd5b506105bf611892565b6040516105cc9190612f69565b60405180910390f35b3480156105e157600080fd5b506105ea611897565b6040516105f79190612f69565b60405180910390f35b34801561060c57600080fd5b5061061561189d565b6040516106229190613251565b60405180910390f35b34801561063757600080fd5b506106406118c7565b60405161064d91906130e3565b60405180910390f35b34801561066257600080fd5b5061067d600480360381019061067891906133d6565b611959565b005b34801561068b57600080fd5b50610694611ad0565b005b3480156106a257600080fd5b506106ab611b69565b6040516106b89190612f69565b60405180910390f35b3480156106cd57600080fd5b506106e860048036038101906106e3919061332b565b611b6f565b6040516106f59190612f69565b60405180910390f35b610718600480360381019061071391906131e3565b611b87565b005b34801561072657600080fd5b50610741600480360381019061073c91906134c2565b611fde565b005b34801561074f57600080fd5b5061076a60048036038101906107659190613673565b612163565b005b34801561077857600080fd5b506107816121d6565b60405161078e9190612f69565b60405180910390f35b3480156107a357600080fd5b506107be60048036038101906107b991906131e3565b6121db565b6040516107cb91906130e3565b60405180910390f35b3480156107e057600080fd5b506107fb60048036038101906107f691906136f6565b6122d3565b005b34801561080957600080fd5b50610824600480360381019061081f9190613743565b6123df565b6040516108319190613038565b60405180910390f35b34801561084657600080fd5b50610861600480360381019061085c919061332b565b612473565b005b34801561086f57600080fd5b5061087861256a565b6040516108859190612f69565b60405180910390f35b34801561089a57600080fd5b506108b560048036038101906108b09190613783565b612570565b005b3480156108c357600080fd5b506108cc6125fe565b6040516108d9919061383a565b60405180910390f35b600f5481565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061094357506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109735750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461098990613884565b80601f01602080910402602001604051908101604052809291908181526020018280546109b590613884565b8015610a025780601f106109d757610100808354040283529160200191610a02565b820191906000526020600020905b8154815290600101906020018083116109e557829003601f168201915b5050505050905090565b610a14612611565b73ffffffffffffffffffffffffffffffffffffffff16610a3261189d565b73ffffffffffffffffffffffffffffffffffffffff1614610a88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7f90613901565b60405180910390fd5b8181600a9182610a99929190613ad8565b505050565b6000610aa982612619565b610adf576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610b2582611728565b90508073ffffffffffffffffffffffffffffffffffffffff16610b46612678565b73ffffffffffffffffffffffffffffffffffffffff1614610ba957610b7281610b6d612678565b6123df565b610ba8576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610c65612680565b6001546000540303905090565b6000610c7d82612685565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ce4576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610cf084612751565b91509150610d068187610d01612678565b612773565b610d5257610d1b86610d16612678565b6123df565b610d51576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610db8576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dc586868660016127b7565b8015610dd057600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610e9e85610e7a8888876127bd565b7c0200000000000000000000000000000000000000000000000000000000176127e5565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610f245760006001850190506000600460008381526020019081526020016000205403610f22576000548114610f21578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610f8c8686866001612810565b505050505050565b606481565b8060006003811115610fae57610fad6137c3565b5b601060009054906101000a900460ff166003811115610fd057610fcf6137c3565b5b03611010576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100790613bf4565b60405180910390fd5b60008111611053576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104a90613c60565b60405180910390fd5b600c548161105f610c5b565b6110699190613caf565b11156110aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110a190613d2f565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614611118576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110f90613dc1565b60405180910390fd5b6002600381111561112c5761112b6137c3565b5b601060009054906101000a900460ff16600381111561114e5761114d6137c3565b5b1461118e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118590613e2d565b60405180910390fd5b601482601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546111db9190613caf565b111561121c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121390613ebf565b60405180910390fd5b81600e5461122a9190613edf565b341461126b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161126290613f6d565b60405180910390fd5b81601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546112ba9190613caf565b925050819055506112cb3383612816565b5050565b80600060038111156112e4576112e36137c3565b5b601060009054906101000a900460ff166003811115611306576113056137c3565b5b03611346576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133d90613bf4565b60405180910390fd5b60008111611389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138090613c60565b60405180910390fd5b600c5481611395610c5b565b61139f9190613caf565b11156113e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d790613d2f565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff161461144e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144590613dc1565b60405180910390fd5b600380811115611461576114606137c3565b5b601060009054906101000a900460ff166003811115611483576114826137c3565b5b146114c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ba90613fd9565b60405180910390fd5b81600f546114d19190613edf565b3414611512576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161150990614045565b60405180910390fd5b61151c3383612816565b5050565b611528612611565b73ffffffffffffffffffffffffffffffffffffffff1661154661189d565b73ffffffffffffffffffffffffffffffffffffffff161461159c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159390613901565b60405180910390fd5b60004790506115b26115ac61189d565b82612834565b50565b6115d083838360405180602001604052806000815250612163565b505050565b60126020528060005260406000206000915090505481565b6115f5612611565b73ffffffffffffffffffffffffffffffffffffffff1661161361189d565b73ffffffffffffffffffffffffffffffffffffffff1614611669576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166090613901565b60405180910390fd5b80601060006101000a81548160ff0219169083600381111561168e5761168d6137c3565b5b021790555050565b61169e612611565b73ffffffffffffffffffffffffffffffffffffffff166116bc61189d565b73ffffffffffffffffffffffffffffffffffffffff1614611712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170990613901565b60405180910390fd5b818160099182611723929190613ad8565b505050565b600061173382612685565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036117a1576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6117fa612611565b73ffffffffffffffffffffffffffffffffffffffff1661181861189d565b73ffffffffffffffffffffffffffffffffffffffff161461186e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186590613901565b60405180910390fd5b6118786000612928565b565b60116020528060005260406000206000915090505481565b601481565b600d5481565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600380546118d690613884565b80601f016020809104026020016040519081016040528092919081815260200182805461190290613884565b801561194f5780601f106119245761010080835404028352916020019161194f565b820191906000526020600020905b81548152906001019060200180831161193257829003601f168201915b5050505050905090565b611961612678565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036119c5576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600760006119d2612678565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611a7f612678565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611ac49190613038565b60405180910390a35050565b611ad8612611565b73ffffffffffffffffffffffffffffffffffffffff16611af661189d565b73ffffffffffffffffffffffffffffffffffffffff1614611b4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4390613901565b60405180910390fd5b6001600b60006101000a81548160ff021916908315150217905550565b600e5481565b60136020528060005260406000206000915090505481565b8060006003811115611b9c57611b9b6137c3565b5b601060009054906101000a900460ff166003811115611bbe57611bbd6137c3565b5b03611bfe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf590613bf4565b60405180910390fd5b60008111611c41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3890613c60565b60405180910390fd5b600c5481611c4d610c5b565b611c579190613caf565b1115611c98576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8f90613d2f565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614611d06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cfd90613dc1565b60405180910390fd5b60016003811115611d1a57611d196137c3565b5b601060009054906101000a900460ff166003811115611d3c57611d3b6137c3565b5b14611d7c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d73906140b1565b60405180910390fd5b6000601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008111611e03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dfa9061411d565b60405180910390fd5b80831115611e46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e3d90614189565b60405180910390fd5b601483601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611e939190613caf565b1115611ed4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ecb90613ebf565b60405180910390fd5b82600d54611ee29190613edf565b3414611f23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1a90613f6d565b60405180910390fd5b82601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f7291906141a9565b9250508190555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611fc89190613caf565b92505081905550611fd93384612816565b505050565b611fe6612611565b73ffffffffffffffffffffffffffffffffffffffff1661200461189d565b73ffffffffffffffffffffffffffffffffffffffff161461205a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205190613901565b60405180910390fd5b60005b8484905081101561215c57601483838381811061207d5761207c6141dd565b5b9050602002013511156120c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120bc90614258565b60405180910390fd5b8282828181106120d8576120d76141dd565b5b90506020020135601160008787858181106120f6576120f56141dd565b5b905060200201602081019061210b919061332b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550808061215490614278565b91505061205d565b5050505050565b61216e848484610c72565b60008373ffffffffffffffffffffffffffffffffffffffff163b146121d057612199848484846129ee565b6121cf576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b601481565b60606121e682612619565b61221c576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b60009054906101000a900460ff166122c257600a805461223d90613884565b80601f016020809104026020016040519081016040528092919081815260200182805461226990613884565b80156122b65780601f1061228b576101008083540402835291602001916122b6565b820191906000526020600020905b81548152906001019060200180831161229957829003601f168201915b505050505090506122ce565b6122cb82612b3e565b90505b919050565b6122db612611565b73ffffffffffffffffffffffffffffffffffffffff166122f961189d565b73ffffffffffffffffffffffffffffffffffffffff161461234f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161234690613901565b60405180910390fd5b60005b828290508110156123da5760116000848484818110612374576123736141dd565b5b9050602002016020810190612389919061332b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000905580806123d290614278565b915050612352565b505050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61247b612611565b73ffffffffffffffffffffffffffffffffffffffff1661249961189d565b73ffffffffffffffffffffffffffffffffffffffff16146124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e690613901565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361255e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161255590614332565b60405180910390fd5b61256781612928565b50565b600c5481565b612578612611565b73ffffffffffffffffffffffffffffffffffffffff1661259661189d565b73ffffffffffffffffffffffffffffffffffffffff16146125ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125e390613901565b60405180910390fd5b81600e8190555080600f819055505050565b601060009054906101000a900460ff1681565b600033905090565b600081612624612680565b11158015612633575060005482105b8015612671575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600090565b60008082905080612694612680565b1161271a576000548110156127195760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603612717575b6000810361270d5760046000836001900393508381526020019081526020016000205490506126e3565b809250505061274c565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000806000600690508360005280602052604060002092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e86127d4868684612bdc565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b612830828260405180602001604052806000815250612be5565b5050565b80471015612877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161286e9061439e565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405161289d906143ef565b60006040518083038185875af1925050503d80600081146128da576040519150601f19603f3d011682016040523d82523d6000602084013e6128df565b606091505b5050905080612923576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161291a90614476565b60405180910390fd5b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612a14612678565b8786866040518563ffffffff1660e01b8152600401612a3694939291906144eb565b6020604051808303816000875af1925050508015612a7257506040513d601f19601f82011682018060405250810190612a6f919061454c565b60015b612aeb573d8060008114612aa2576040519150601f19603f3d011682016040523d82523d6000602084013e612aa7565b606091505b506000815103612ae3576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060612b4982612619565b612b7f576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612b89612c82565b90506000815103612ba95760405180602001604052806000815250612bd4565b80612bb384612d14565b604051602001612bc49291906145b5565b6040516020818303038152906040525b915050919050565b60009392505050565b612bef8383612d6e565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612c7d57600080549050600083820390505b612c2f60008683806001019450866129ee565b612c65576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110612c1c578160005414612c7a57600080fd5b50505b505050565b606060098054612c9190613884565b80601f0160208091040260200160405190810160405280929190818152602001828054612cbd90613884565b8015612d0a5780601f10612cdf57610100808354040283529160200191612d0a565b820191906000526020600020905b815481529060010190602001808311612ced57829003601f168201915b5050505050905090565b60606080604051019050806040528082600183039250600a81066030018353600a810490505b8015612d5a57600183039250600a81066030018353600a81049050612d3a565b508181036020830392508083525050919050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612dda576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008203612e14576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e2160008483856127b7565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612e9883612e8960008660006127bd565b612e9285612f40565b176127e5565b60046000838152602001908152602001600020819055506000819050600083830190505b818060010192508573ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808210612ebc57806000819055505050612f3b6000848385612810565b505050565b60006001821460e11b9050919050565b6000819050919050565b612f6381612f50565b82525050565b6000602082019050612f7e6000830184612f5a565b92915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fcd81612f98565b8114612fd857600080fd5b50565b600081359050612fea81612fc4565b92915050565b60006020828403121561300657613005612f8e565b5b600061301484828501612fdb565b91505092915050565b60008115159050919050565b6130328161301d565b82525050565b600060208201905061304d6000830184613029565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561308d578082015181840152602081019050613072565b60008484015250505050565b6000601f19601f8301169050919050565b60006130b582613053565b6130bf818561305e565b93506130cf81856020860161306f565b6130d881613099565b840191505092915050565b600060208201905081810360008301526130fd81846130aa565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261312a57613129613105565b5b8235905067ffffffffffffffff8111156131475761314661310a565b5b6020830191508360018202830111156131635761316261310f565b5b9250929050565b6000806020838503121561318157613180612f8e565b5b600083013567ffffffffffffffff81111561319f5761319e612f93565b5b6131ab85828601613114565b92509250509250929050565b6131c081612f50565b81146131cb57600080fd5b50565b6000813590506131dd816131b7565b92915050565b6000602082840312156131f9576131f8612f8e565b5b6000613207848285016131ce565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061323b82613210565b9050919050565b61324b81613230565b82525050565b60006020820190506132666000830184613242565b92915050565b61327581613230565b811461328057600080fd5b50565b6000813590506132928161326c565b92915050565b600080604083850312156132af576132ae612f8e565b5b60006132bd85828601613283565b92505060206132ce858286016131ce565b9150509250929050565b6000806000606084860312156132f1576132f0612f8e565b5b60006132ff86828701613283565b935050602061331086828701613283565b9250506040613321868287016131ce565b9150509250925092565b60006020828403121561334157613340612f8e565b5b600061334f84828501613283565b91505092915050565b6004811061336557600080fd5b50565b60008135905061337781613358565b92915050565b60006020828403121561339357613392612f8e565b5b60006133a184828501613368565b91505092915050565b6133b38161301d565b81146133be57600080fd5b50565b6000813590506133d0816133aa565b92915050565b600080604083850312156133ed576133ec612f8e565b5b60006133fb85828601613283565b925050602061340c858286016133c1565b9150509250929050565b60008083601f84011261342c5761342b613105565b5b8235905067ffffffffffffffff8111156134495761344861310a565b5b6020830191508360208202830111156134655761346461310f565b5b9250929050565b60008083601f84011261348257613481613105565b5b8235905067ffffffffffffffff81111561349f5761349e61310a565b5b6020830191508360208202830111156134bb576134ba61310f565b5b9250929050565b600080600080604085870312156134dc576134db612f8e565b5b600085013567ffffffffffffffff8111156134fa576134f9612f93565b5b61350687828801613416565b9450945050602085013567ffffffffffffffff81111561352957613528612f93565b5b6135358782880161346c565b925092505092959194509250565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61358082613099565b810181811067ffffffffffffffff8211171561359f5761359e613548565b5b80604052505050565b60006135b2612f84565b90506135be8282613577565b919050565b600067ffffffffffffffff8211156135de576135dd613548565b5b6135e782613099565b9050602081019050919050565b82818337600083830152505050565b6000613616613611846135c3565b6135a8565b90508281526020810184848401111561363257613631613543565b5b61363d8482856135f4565b509392505050565b600082601f83011261365a57613659613105565b5b813561366a848260208601613603565b91505092915050565b6000806000806080858703121561368d5761368c612f8e565b5b600061369b87828801613283565b94505060206136ac87828801613283565b93505060406136bd878288016131ce565b925050606085013567ffffffffffffffff8111156136de576136dd612f93565b5b6136ea87828801613645565b91505092959194509250565b6000806020838503121561370d5761370c612f8e565b5b600083013567ffffffffffffffff81111561372b5761372a612f93565b5b61373785828601613416565b92509250509250929050565b6000806040838503121561375a57613759612f8e565b5b600061376885828601613283565b925050602061377985828601613283565b9150509250929050565b6000806040838503121561379a57613799612f8e565b5b60006137a8858286016131ce565b92505060206137b9858286016131ce565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110613803576138026137c3565b5b50565b6000819050613814826137f2565b919050565b600061382482613806565b9050919050565b61383481613819565b82525050565b600060208201905061384f600083018461382b565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061389c57607f821691505b6020821081036138af576138ae613855565b5b50919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006138eb60208361305e565b91506138f6826138b5565b602082019050919050565b6000602082019050818103600083015261391a816138de565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261398e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613951565b6139988683613951565b95508019841693508086168417925050509392505050565b6000819050919050565b60006139d56139d06139cb84612f50565b6139b0565b612f50565b9050919050565b6000819050919050565b6139ef836139ba565b613a036139fb826139dc565b84845461395e565b825550505050565b600090565b613a18613a0b565b613a238184846139e6565b505050565b5b81811015613a4757613a3c600082613a10565b600181019050613a29565b5050565b601f821115613a8c57613a5d8161392c565b613a6684613941565b81016020851015613a75578190505b613a89613a8185613941565b830182613a28565b50505b505050565b600082821c905092915050565b6000613aaf60001984600802613a91565b1980831691505092915050565b6000613ac88383613a9e565b9150826002028217905092915050565b613ae28383613921565b67ffffffffffffffff811115613afb57613afa613548565b5b613b058254613884565b613b10828285613a4b565b6000601f831160018114613b3f5760008415613b2d578287013590505b613b378582613abc565b865550613b9f565b601f198416613b4d8661392c565b60005b82811015613b7557848901358255600182019150602085019450602081019050613b50565b86831015613b925784890135613b8e601f891682613a9e565b8355505b6001600288020188555050505b50505050505050565b7f73616c65206973206e6f74206163746976650000000000000000000000000000600082015250565b6000613bde60128361305e565b9150613be982613ba8565b602082019050919050565b60006020820190508181036000830152613c0d81613bd1565b9050919050565b7f6d757374206d696e74206174206c65617374206f6e6520746f6b656e00000000600082015250565b6000613c4a601c8361305e565b9150613c5582613c14565b602082019050919050565b60006020820190508181036000830152613c7981613c3d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613cba82612f50565b9150613cc583612f50565b9250828201905080821115613cdd57613cdc613c80565b5b92915050565b7f6d696e74696e6720776f756c6420657863656564206d617820737570706c7900600082015250565b6000613d19601f8361305e565b9150613d2482613ce3565b602082019050919050565b60006020820190508181036000830152613d4881613d0c565b9050919050565b7f636f6e7472616374732063616e6e6f742063616c6c207468697320636f6e747260008201527f6163740000000000000000000000000000000000000000000000000000000000602082015250565b6000613dab60238361305e565b9150613db682613d4f565b604082019050919050565b60006020820190508181036000830152613dda81613d9e565b9050919050565b7f7075626c6963206d696e74206e6f742061637469766500000000000000000000600082015250565b6000613e1760168361305e565b9150613e2282613de1565b602082019050919050565b60006020820190508181036000830152613e4681613e0a565b9050919050565b7f6d696e74696e6720657863656564732061646472657373206c696d6974206f6660008201527f2032300000000000000000000000000000000000000000000000000000000000602082015250565b6000613ea960238361305e565b9150613eb482613e4d565b604082019050919050565b60006020820190508181036000830152613ed881613e9c565b9050919050565b6000613eea82612f50565b9150613ef583612f50565b9250828202613f0381612f50565b91508282048414831517613f1a57613f19613c80565b5b5092915050565b7f657468657275656d2073656e7420696e636f7272656374000000000000000000600082015250565b6000613f5760178361305e565b9150613f6282613f21565b602082019050919050565b60006020820190508181036000830152613f8681613f4a565b9050919050565b7f756e6c696d69746564206d696e74206973206e6f742061637469766500000000600082015250565b6000613fc3601c8361305e565b9150613fce82613f8d565b602082019050919050565b60006020820190508181036000830152613ff281613fb6565b9050919050565b7f657468657265756d2073656e7420696e636f7272656374000000000000000000600082015250565b600061402f60178361305e565b915061403a82613ff9565b602082019050919050565b6000602082019050818103600083015261405e81614022565b9050919050565b7f70726976617465206d696e74206e6f7420616374697665000000000000000000600082015250565b600061409b60178361305e565b91506140a682614065565b602082019050919050565b600060208201905081810360008301526140ca8161408e565b9050919050565b7f6e6f7420696e20616c6c6f776c69737400000000000000000000000000000000600082015250565b600061410760108361305e565b9150614112826140d1565b602082019050919050565b60006020820190508181036000830152614136816140fa565b9050919050565b7f6d696e74696e67206578636565647320616c6c6f776c697374206c696d697400600082015250565b6000614173601f8361305e565b915061417e8261413d565b602082019050919050565b600060208201905081810360008301526141a281614166565b9050919050565b60006141b482612f50565b91506141bf83612f50565b92508282039050818111156141d7576141d6613c80565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f616d6f756e7420776f756c6420657863656564206d617820616c6c6f77656400600082015250565b6000614242601f8361305e565b915061424d8261420c565b602082019050919050565b6000602082019050818103600083015261427181614235565b9050919050565b600061428382612f50565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036142b5576142b4613c80565b5b600182019050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061431c60268361305e565b9150614327826142c0565b604082019050919050565b6000602082019050818103600083015261434b8161430f565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b6000614388601d8361305e565b915061439382614352565b602082019050919050565b600060208201905081810360008301526143b78161437b565b9050919050565b600081905092915050565b50565b60006143d96000836143be565b91506143e4826143c9565b600082019050919050565b60006143fa826143cc565b9150819050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b6000614460603a8361305e565b915061446b82614404565b604082019050919050565b6000602082019050818103600083015261448f81614453565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006144bd82614496565b6144c781856144a1565b93506144d781856020860161306f565b6144e081613099565b840191505092915050565b60006080820190506145006000830187613242565b61450d6020830186613242565b61451a6040830185612f5a565b818103606083015261452c81846144b2565b905095945050505050565b60008151905061454681612fc4565b92915050565b60006020828403121561456257614561612f8e565b5b600061457084828501614537565b91505092915050565b600081905092915050565b600061458f82613053565b6145998185614579565b93506145a981856020860161306f565b80840191505092915050565b60006145c18285614584565b91506145cd8284614584565b9150819050939250505056fea2646970667358221220b9f857ba2cb9693fc247e9a6535b4558af5ae8bfc10b6f591f2e72659ab01a5f64736f6c63430008110033697066733a2f2f6261667962656963703273756f6c696232757068746e36376d6b6b7235626773627a79647474626b6e7770706d74333370766f78696b757370356d

Deployed Bytecode

0x60806040526004361061022f5760003560e01c806374df85b61161012e578063b0686def116100ab578063e985e9c51161006f578063e985e9c5146107fd578063f2fde38b1461083a578063f47c84c514610863578063f7d975771461088e578063f9020e33146108b75761022f565b8063b0686def1461071a578063b88d4fde14610743578063c5da5cbe1461076c578063c87b56dd14610797578063e373934e146107d45761022f565b8063a22cb465116100f2578063a22cb46514610656578063a475b5dd1461067f578063a945bf8014610696578063aad66a12146106c1578063abfe40a8146106fe5761022f565b806374df85b61461056d578063774ede13146105aa57806387c0568b146105d55780638da5cb5b1461060057806395d89b411461062b5761022f565b80632db11544116101bc5780634891ad88116101805780634891ad881461048a57806355f804b3146104b35780636352211e146104dc57806370a0823114610519578063715018a6146105565761022f565b80632db11544146103d557806339c6da89146103f15780633ccfd60b1461040d57806342842e0e146104245780634346fbc81461044d5761022f565b8063081812fc11610203578063081812fc146102f0578063095ea7b31461032d57806318160ddd1461035657806323b872dd1461038157806328c95017146103aa5761022f565b8062d2cc8e1461023457806301ffc9a71461025f57806306fdde031461029c578063078eef28146102c7575b600080fd5b34801561024057600080fd5b506102496108e2565b6040516102569190612f69565b60405180910390f35b34801561026b57600080fd5b5061028660048036038101906102819190612ff0565b6108e8565b6040516102939190613038565b60405180910390f35b3480156102a857600080fd5b506102b161097a565b6040516102be91906130e3565b60405180910390f35b3480156102d357600080fd5b506102ee60048036038101906102e9919061316a565b610a0c565b005b3480156102fc57600080fd5b50610317600480360381019061031291906131e3565b610a9e565b6040516103249190613251565b60405180910390f35b34801561033957600080fd5b50610354600480360381019061034f9190613298565b610b1a565b005b34801561036257600080fd5b5061036b610c5b565b6040516103789190612f69565b60405180910390f35b34801561038d57600080fd5b506103a860048036038101906103a391906132d8565b610c72565b005b3480156103b657600080fd5b506103bf610f94565b6040516103cc9190612f69565b60405180910390f35b6103ef60048036038101906103ea91906131e3565b610f99565b005b61040b600480360381019061040691906131e3565b6112cf565b005b34801561041957600080fd5b50610422611520565b005b34801561043057600080fd5b5061044b600480360381019061044691906132d8565b6115b5565b005b34801561045957600080fd5b50610474600480360381019061046f919061332b565b6115d5565b6040516104819190612f69565b60405180910390f35b34801561049657600080fd5b506104b160048036038101906104ac919061337d565b6115ed565b005b3480156104bf57600080fd5b506104da60048036038101906104d5919061316a565b611696565b005b3480156104e857600080fd5b5061050360048036038101906104fe91906131e3565b611728565b6040516105109190613251565b60405180910390f35b34801561052557600080fd5b50610540600480360381019061053b919061332b565b61173a565b60405161054d9190612f69565b60405180910390f35b34801561056257600080fd5b5061056b6117f2565b005b34801561057957600080fd5b50610594600480360381019061058f919061332b565b61187a565b6040516105a19190612f69565b60405180910390f35b3480156105b657600080fd5b506105bf611892565b6040516105cc9190612f69565b60405180910390f35b3480156105e157600080fd5b506105ea611897565b6040516105f79190612f69565b60405180910390f35b34801561060c57600080fd5b5061061561189d565b6040516106229190613251565b60405180910390f35b34801561063757600080fd5b506106406118c7565b60405161064d91906130e3565b60405180910390f35b34801561066257600080fd5b5061067d600480360381019061067891906133d6565b611959565b005b34801561068b57600080fd5b50610694611ad0565b005b3480156106a257600080fd5b506106ab611b69565b6040516106b89190612f69565b60405180910390f35b3480156106cd57600080fd5b506106e860048036038101906106e3919061332b565b611b6f565b6040516106f59190612f69565b60405180910390f35b610718600480360381019061071391906131e3565b611b87565b005b34801561072657600080fd5b50610741600480360381019061073c91906134c2565b611fde565b005b34801561074f57600080fd5b5061076a60048036038101906107659190613673565b612163565b005b34801561077857600080fd5b506107816121d6565b60405161078e9190612f69565b60405180910390f35b3480156107a357600080fd5b506107be60048036038101906107b991906131e3565b6121db565b6040516107cb91906130e3565b60405180910390f35b3480156107e057600080fd5b506107fb60048036038101906107f691906136f6565b6122d3565b005b34801561080957600080fd5b50610824600480360381019061081f9190613743565b6123df565b6040516108319190613038565b60405180910390f35b34801561084657600080fd5b50610861600480360381019061085c919061332b565b612473565b005b34801561086f57600080fd5b5061087861256a565b6040516108859190612f69565b60405180910390f35b34801561089a57600080fd5b506108b560048036038101906108b09190613783565b612570565b005b3480156108c357600080fd5b506108cc6125fe565b6040516108d9919061383a565b60405180910390f35b600f5481565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061094357506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806109735750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461098990613884565b80601f01602080910402602001604051908101604052809291908181526020018280546109b590613884565b8015610a025780601f106109d757610100808354040283529160200191610a02565b820191906000526020600020905b8154815290600101906020018083116109e557829003601f168201915b5050505050905090565b610a14612611565b73ffffffffffffffffffffffffffffffffffffffff16610a3261189d565b73ffffffffffffffffffffffffffffffffffffffff1614610a88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7f90613901565b60405180910390fd5b8181600a9182610a99929190613ad8565b505050565b6000610aa982612619565b610adf576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610b2582611728565b90508073ffffffffffffffffffffffffffffffffffffffff16610b46612678565b73ffffffffffffffffffffffffffffffffffffffff1614610ba957610b7281610b6d612678565b6123df565b610ba8576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610c65612680565b6001546000540303905090565b6000610c7d82612685565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ce4576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610cf084612751565b91509150610d068187610d01612678565b612773565b610d5257610d1b86610d16612678565b6123df565b610d51576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610db8576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dc586868660016127b7565b8015610dd057600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610e9e85610e7a8888876127bd565b7c0200000000000000000000000000000000000000000000000000000000176127e5565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610f245760006001850190506000600460008381526020019081526020016000205403610f22576000548114610f21578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610f8c8686866001612810565b505050505050565b606481565b8060006003811115610fae57610fad6137c3565b5b601060009054906101000a900460ff166003811115610fd057610fcf6137c3565b5b03611010576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100790613bf4565b60405180910390fd5b60008111611053576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161104a90613c60565b60405180910390fd5b600c548161105f610c5b565b6110699190613caf565b11156110aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110a190613d2f565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614611118576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110f90613dc1565b60405180910390fd5b6002600381111561112c5761112b6137c3565b5b601060009054906101000a900460ff16600381111561114e5761114d6137c3565b5b1461118e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118590613e2d565b60405180910390fd5b601482601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546111db9190613caf565b111561121c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121390613ebf565b60405180910390fd5b81600e5461122a9190613edf565b341461126b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161126290613f6d565b60405180910390fd5b81601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546112ba9190613caf565b925050819055506112cb3383612816565b5050565b80600060038111156112e4576112e36137c3565b5b601060009054906101000a900460ff166003811115611306576113056137c3565b5b03611346576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133d90613bf4565b60405180910390fd5b60008111611389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138090613c60565b60405180910390fd5b600c5481611395610c5b565b61139f9190613caf565b11156113e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d790613d2f565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff161461144e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144590613dc1565b60405180910390fd5b600380811115611461576114606137c3565b5b601060009054906101000a900460ff166003811115611483576114826137c3565b5b146114c3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ba90613fd9565b60405180910390fd5b81600f546114d19190613edf565b3414611512576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161150990614045565b60405180910390fd5b61151c3383612816565b5050565b611528612611565b73ffffffffffffffffffffffffffffffffffffffff1661154661189d565b73ffffffffffffffffffffffffffffffffffffffff161461159c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159390613901565b60405180910390fd5b60004790506115b26115ac61189d565b82612834565b50565b6115d083838360405180602001604052806000815250612163565b505050565b60126020528060005260406000206000915090505481565b6115f5612611565b73ffffffffffffffffffffffffffffffffffffffff1661161361189d565b73ffffffffffffffffffffffffffffffffffffffff1614611669576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166090613901565b60405180910390fd5b80601060006101000a81548160ff0219169083600381111561168e5761168d6137c3565b5b021790555050565b61169e612611565b73ffffffffffffffffffffffffffffffffffffffff166116bc61189d565b73ffffffffffffffffffffffffffffffffffffffff1614611712576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170990613901565b60405180910390fd5b818160099182611723929190613ad8565b505050565b600061173382612685565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036117a1576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6117fa612611565b73ffffffffffffffffffffffffffffffffffffffff1661181861189d565b73ffffffffffffffffffffffffffffffffffffffff161461186e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186590613901565b60405180910390fd5b6118786000612928565b565b60116020528060005260406000206000915090505481565b601481565b600d5481565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600380546118d690613884565b80601f016020809104026020016040519081016040528092919081815260200182805461190290613884565b801561194f5780601f106119245761010080835404028352916020019161194f565b820191906000526020600020905b81548152906001019060200180831161193257829003601f168201915b5050505050905090565b611961612678565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036119c5576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600760006119d2612678565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611a7f612678565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611ac49190613038565b60405180910390a35050565b611ad8612611565b73ffffffffffffffffffffffffffffffffffffffff16611af661189d565b73ffffffffffffffffffffffffffffffffffffffff1614611b4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4390613901565b60405180910390fd5b6001600b60006101000a81548160ff021916908315150217905550565b600e5481565b60136020528060005260406000206000915090505481565b8060006003811115611b9c57611b9b6137c3565b5b601060009054906101000a900460ff166003811115611bbe57611bbd6137c3565b5b03611bfe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf590613bf4565b60405180910390fd5b60008111611c41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3890613c60565b60405180910390fd5b600c5481611c4d610c5b565b611c579190613caf565b1115611c98576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8f90613d2f565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614611d06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cfd90613dc1565b60405180910390fd5b60016003811115611d1a57611d196137c3565b5b601060009054906101000a900460ff166003811115611d3c57611d3b6137c3565b5b14611d7c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d73906140b1565b60405180910390fd5b6000601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008111611e03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dfa9061411d565b60405180910390fd5b80831115611e46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e3d90614189565b60405180910390fd5b601483601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611e939190613caf565b1115611ed4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ecb90613ebf565b60405180910390fd5b82600d54611ee29190613edf565b3414611f23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1a90613f6d565b60405180910390fd5b82601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611f7291906141a9565b9250508190555082601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611fc89190613caf565b92505081905550611fd93384612816565b505050565b611fe6612611565b73ffffffffffffffffffffffffffffffffffffffff1661200461189d565b73ffffffffffffffffffffffffffffffffffffffff161461205a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205190613901565b60405180910390fd5b60005b8484905081101561215c57601483838381811061207d5761207c6141dd565b5b9050602002013511156120c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120bc90614258565b60405180910390fd5b8282828181106120d8576120d76141dd565b5b90506020020135601160008787858181106120f6576120f56141dd565b5b905060200201602081019061210b919061332b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550808061215490614278565b91505061205d565b5050505050565b61216e848484610c72565b60008373ffffffffffffffffffffffffffffffffffffffff163b146121d057612199848484846129ee565b6121cf576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b601481565b60606121e682612619565b61221c576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b60009054906101000a900460ff166122c257600a805461223d90613884565b80601f016020809104026020016040519081016040528092919081815260200182805461226990613884565b80156122b65780601f1061228b576101008083540402835291602001916122b6565b820191906000526020600020905b81548152906001019060200180831161229957829003601f168201915b505050505090506122ce565b6122cb82612b3e565b90505b919050565b6122db612611565b73ffffffffffffffffffffffffffffffffffffffff166122f961189d565b73ffffffffffffffffffffffffffffffffffffffff161461234f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161234690613901565b60405180910390fd5b60005b828290508110156123da5760116000848484818110612374576123736141dd565b5b9050602002016020810190612389919061332b565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000905580806123d290614278565b915050612352565b505050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61247b612611565b73ffffffffffffffffffffffffffffffffffffffff1661249961189d565b73ffffffffffffffffffffffffffffffffffffffff16146124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e690613901565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361255e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161255590614332565b60405180910390fd5b61256781612928565b50565b600c5481565b612578612611565b73ffffffffffffffffffffffffffffffffffffffff1661259661189d565b73ffffffffffffffffffffffffffffffffffffffff16146125ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125e390613901565b60405180910390fd5b81600e8190555080600f819055505050565b601060009054906101000a900460ff1681565b600033905090565b600081612624612680565b11158015612633575060005482105b8015612671575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600090565b60008082905080612694612680565b1161271a576000548110156127195760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603612717575b6000810361270d5760046000836001900393508381526020019081526020016000205490506126e3565b809250505061274c565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000806000600690508360005280602052604060002092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e86127d4868684612bdc565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b612830828260405180602001604052806000815250612be5565b5050565b80471015612877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161286e9061439e565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405161289d906143ef565b60006040518083038185875af1925050503d80600081146128da576040519150601f19603f3d011682016040523d82523d6000602084013e6128df565b606091505b5050905080612923576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161291a90614476565b60405180910390fd5b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612a14612678565b8786866040518563ffffffff1660e01b8152600401612a3694939291906144eb565b6020604051808303816000875af1925050508015612a7257506040513d601f19601f82011682018060405250810190612a6f919061454c565b60015b612aeb573d8060008114612aa2576040519150601f19603f3d011682016040523d82523d6000602084013e612aa7565b606091505b506000815103612ae3576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060612b4982612619565b612b7f576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612b89612c82565b90506000815103612ba95760405180602001604052806000815250612bd4565b80612bb384612d14565b604051602001612bc49291906145b5565b6040516020818303038152906040525b915050919050565b60009392505050565b612bef8383612d6e565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612c7d57600080549050600083820390505b612c2f60008683806001019450866129ee565b612c65576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b818110612c1c578160005414612c7a57600080fd5b50505b505050565b606060098054612c9190613884565b80601f0160208091040260200160405190810160405280929190818152602001828054612cbd90613884565b8015612d0a5780601f10612cdf57610100808354040283529160200191612d0a565b820191906000526020600020905b815481529060010190602001808311612ced57829003601f168201915b5050505050905090565b60606080604051019050806040528082600183039250600a81066030018353600a810490505b8015612d5a57600183039250600a81066030018353600a81049050612d3a565b508181036020830392508083525050919050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612dda576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008203612e14576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e2160008483856127b7565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612e9883612e8960008660006127bd565b612e9285612f40565b176127e5565b60046000838152602001908152602001600020819055506000819050600083830190505b818060010192508573ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4808210612ebc57806000819055505050612f3b6000848385612810565b505050565b60006001821460e11b9050919050565b6000819050919050565b612f6381612f50565b82525050565b6000602082019050612f7e6000830184612f5a565b92915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612fcd81612f98565b8114612fd857600080fd5b50565b600081359050612fea81612fc4565b92915050565b60006020828403121561300657613005612f8e565b5b600061301484828501612fdb565b91505092915050565b60008115159050919050565b6130328161301d565b82525050565b600060208201905061304d6000830184613029565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561308d578082015181840152602081019050613072565b60008484015250505050565b6000601f19601f8301169050919050565b60006130b582613053565b6130bf818561305e565b93506130cf81856020860161306f565b6130d881613099565b840191505092915050565b600060208201905081810360008301526130fd81846130aa565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261312a57613129613105565b5b8235905067ffffffffffffffff8111156131475761314661310a565b5b6020830191508360018202830111156131635761316261310f565b5b9250929050565b6000806020838503121561318157613180612f8e565b5b600083013567ffffffffffffffff81111561319f5761319e612f93565b5b6131ab85828601613114565b92509250509250929050565b6131c081612f50565b81146131cb57600080fd5b50565b6000813590506131dd816131b7565b92915050565b6000602082840312156131f9576131f8612f8e565b5b6000613207848285016131ce565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061323b82613210565b9050919050565b61324b81613230565b82525050565b60006020820190506132666000830184613242565b92915050565b61327581613230565b811461328057600080fd5b50565b6000813590506132928161326c565b92915050565b600080604083850312156132af576132ae612f8e565b5b60006132bd85828601613283565b92505060206132ce858286016131ce565b9150509250929050565b6000806000606084860312156132f1576132f0612f8e565b5b60006132ff86828701613283565b935050602061331086828701613283565b9250506040613321868287016131ce565b9150509250925092565b60006020828403121561334157613340612f8e565b5b600061334f84828501613283565b91505092915050565b6004811061336557600080fd5b50565b60008135905061337781613358565b92915050565b60006020828403121561339357613392612f8e565b5b60006133a184828501613368565b91505092915050565b6133b38161301d565b81146133be57600080fd5b50565b6000813590506133d0816133aa565b92915050565b600080604083850312156133ed576133ec612f8e565b5b60006133fb85828601613283565b925050602061340c858286016133c1565b9150509250929050565b60008083601f84011261342c5761342b613105565b5b8235905067ffffffffffffffff8111156134495761344861310a565b5b6020830191508360208202830111156134655761346461310f565b5b9250929050565b60008083601f84011261348257613481613105565b5b8235905067ffffffffffffffff81111561349f5761349e61310a565b5b6020830191508360208202830111156134bb576134ba61310f565b5b9250929050565b600080600080604085870312156134dc576134db612f8e565b5b600085013567ffffffffffffffff8111156134fa576134f9612f93565b5b61350687828801613416565b9450945050602085013567ffffffffffffffff81111561352957613528612f93565b5b6135358782880161346c565b925092505092959194509250565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61358082613099565b810181811067ffffffffffffffff8211171561359f5761359e613548565b5b80604052505050565b60006135b2612f84565b90506135be8282613577565b919050565b600067ffffffffffffffff8211156135de576135dd613548565b5b6135e782613099565b9050602081019050919050565b82818337600083830152505050565b6000613616613611846135c3565b6135a8565b90508281526020810184848401111561363257613631613543565b5b61363d8482856135f4565b509392505050565b600082601f83011261365a57613659613105565b5b813561366a848260208601613603565b91505092915050565b6000806000806080858703121561368d5761368c612f8e565b5b600061369b87828801613283565b94505060206136ac87828801613283565b93505060406136bd878288016131ce565b925050606085013567ffffffffffffffff8111156136de576136dd612f93565b5b6136ea87828801613645565b91505092959194509250565b6000806020838503121561370d5761370c612f8e565b5b600083013567ffffffffffffffff81111561372b5761372a612f93565b5b61373785828601613416565b92509250509250929050565b6000806040838503121561375a57613759612f8e565b5b600061376885828601613283565b925050602061377985828601613283565b9150509250929050565b6000806040838503121561379a57613799612f8e565b5b60006137a8858286016131ce565b92505060206137b9858286016131ce565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110613803576138026137c3565b5b50565b6000819050613814826137f2565b919050565b600061382482613806565b9050919050565b61383481613819565b82525050565b600060208201905061384f600083018461382b565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061389c57607f821691505b6020821081036138af576138ae613855565b5b50919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006138eb60208361305e565b91506138f6826138b5565b602082019050919050565b6000602082019050818103600083015261391a816138de565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261398e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613951565b6139988683613951565b95508019841693508086168417925050509392505050565b6000819050919050565b60006139d56139d06139cb84612f50565b6139b0565b612f50565b9050919050565b6000819050919050565b6139ef836139ba565b613a036139fb826139dc565b84845461395e565b825550505050565b600090565b613a18613a0b565b613a238184846139e6565b505050565b5b81811015613a4757613a3c600082613a10565b600181019050613a29565b5050565b601f821115613a8c57613a5d8161392c565b613a6684613941565b81016020851015613a75578190505b613a89613a8185613941565b830182613a28565b50505b505050565b600082821c905092915050565b6000613aaf60001984600802613a91565b1980831691505092915050565b6000613ac88383613a9e565b9150826002028217905092915050565b613ae28383613921565b67ffffffffffffffff811115613afb57613afa613548565b5b613b058254613884565b613b10828285613a4b565b6000601f831160018114613b3f5760008415613b2d578287013590505b613b378582613abc565b865550613b9f565b601f198416613b4d8661392c565b60005b82811015613b7557848901358255600182019150602085019450602081019050613b50565b86831015613b925784890135613b8e601f891682613a9e565b8355505b6001600288020188555050505b50505050505050565b7f73616c65206973206e6f74206163746976650000000000000000000000000000600082015250565b6000613bde60128361305e565b9150613be982613ba8565b602082019050919050565b60006020820190508181036000830152613c0d81613bd1565b9050919050565b7f6d757374206d696e74206174206c65617374206f6e6520746f6b656e00000000600082015250565b6000613c4a601c8361305e565b9150613c5582613c14565b602082019050919050565b60006020820190508181036000830152613c7981613c3d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613cba82612f50565b9150613cc583612f50565b9250828201905080821115613cdd57613cdc613c80565b5b92915050565b7f6d696e74696e6720776f756c6420657863656564206d617820737570706c7900600082015250565b6000613d19601f8361305e565b9150613d2482613ce3565b602082019050919050565b60006020820190508181036000830152613d4881613d0c565b9050919050565b7f636f6e7472616374732063616e6e6f742063616c6c207468697320636f6e747260008201527f6163740000000000000000000000000000000000000000000000000000000000602082015250565b6000613dab60238361305e565b9150613db682613d4f565b604082019050919050565b60006020820190508181036000830152613dda81613d9e565b9050919050565b7f7075626c6963206d696e74206e6f742061637469766500000000000000000000600082015250565b6000613e1760168361305e565b9150613e2282613de1565b602082019050919050565b60006020820190508181036000830152613e4681613e0a565b9050919050565b7f6d696e74696e6720657863656564732061646472657373206c696d6974206f6660008201527f2032300000000000000000000000000000000000000000000000000000000000602082015250565b6000613ea960238361305e565b9150613eb482613e4d565b604082019050919050565b60006020820190508181036000830152613ed881613e9c565b9050919050565b6000613eea82612f50565b9150613ef583612f50565b9250828202613f0381612f50565b91508282048414831517613f1a57613f19613c80565b5b5092915050565b7f657468657275656d2073656e7420696e636f7272656374000000000000000000600082015250565b6000613f5760178361305e565b9150613f6282613f21565b602082019050919050565b60006020820190508181036000830152613f8681613f4a565b9050919050565b7f756e6c696d69746564206d696e74206973206e6f742061637469766500000000600082015250565b6000613fc3601c8361305e565b9150613fce82613f8d565b602082019050919050565b60006020820190508181036000830152613ff281613fb6565b9050919050565b7f657468657265756d2073656e7420696e636f7272656374000000000000000000600082015250565b600061402f60178361305e565b915061403a82613ff9565b602082019050919050565b6000602082019050818103600083015261405e81614022565b9050919050565b7f70726976617465206d696e74206e6f7420616374697665000000000000000000600082015250565b600061409b60178361305e565b91506140a682614065565b602082019050919050565b600060208201905081810360008301526140ca8161408e565b9050919050565b7f6e6f7420696e20616c6c6f776c69737400000000000000000000000000000000600082015250565b600061410760108361305e565b9150614112826140d1565b602082019050919050565b60006020820190508181036000830152614136816140fa565b9050919050565b7f6d696e74696e67206578636565647320616c6c6f776c697374206c696d697400600082015250565b6000614173601f8361305e565b915061417e8261413d565b602082019050919050565b600060208201905081810360008301526141a281614166565b9050919050565b60006141b482612f50565b91506141bf83612f50565b92508282039050818111156141d7576141d6613c80565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f616d6f756e7420776f756c6420657863656564206d617820616c6c6f77656400600082015250565b6000614242601f8361305e565b915061424d8261420c565b602082019050919050565b6000602082019050818103600083015261427181614235565b9050919050565b600061428382612f50565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036142b5576142b4613c80565b5b600182019050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061431c60268361305e565b9150614327826142c0565b604082019050919050565b6000602082019050818103600083015261434b8161430f565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b6000614388601d8361305e565b915061439382614352565b602082019050919050565b600060208201905081810360008301526143b78161437b565b9050919050565b600081905092915050565b50565b60006143d96000836143be565b91506143e4826143c9565b600082019050919050565b60006143fa826143cc565b9150819050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b6000614460603a8361305e565b915061446b82614404565b604082019050919050565b6000602082019050818103600083015261448f81614453565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006144bd82614496565b6144c781856144a1565b93506144d781856020860161306f565b6144e081613099565b840191505092915050565b60006080820190506145006000830187613242565b61450d6020830186613242565b61451a6040830185612f5a565b818103606083015261452c81846144b2565b905095945050505050565b60008151905061454681612fc4565b92915050565b60006020828403121561456257614561612f8e565b5b600061457084828501614537565b91505092915050565b600081905092915050565b600061458f82613053565b6145998185614579565b93506145a981856020860161306f565b80840191505092915050565b60006145c18285614584565b91506145cd8284614584565b9150819050939250505056fea2646970667358221220b9f857ba2cb9693fc247e9a6535b4558af5ae8bfc10b6f591f2e72659ab01a5f64736f6c63430008110033

Deployed Bytecode Sourcemap

87135:4919:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87694:43;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14592:615;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;20239:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88810:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;22185:204;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21733:386;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;13646:315;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31450:2800;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87398:49;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91107:469;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;91584:307;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;91899:152;;;;;;;;;;;;;:::i;:::-;;23075:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87862:49;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;89267:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88702:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;20028:144;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;15271:224;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49454:103;;;;;;;;;;;;;:::i;:::-;;87807:48;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87454:56;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87579:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48803:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;20408:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22461:308;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;89188:71;;;;;;;;;;;;;:::i;:::-;;87637:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87918:48;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90394:705;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;89394:335;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;23331:399;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87517:55;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88923:257;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;89772:210;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;22840:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49712:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87358:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90026:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87754:46;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87694:43;;;;:::o;14592:615::-;14677:4;14992:10;14977:25;;:11;:25;;;;:102;;;;15069:10;15054:25;;:11;:25;;;;14977:102;:179;;;;15146:10;15131:25;;:11;:25;;;;14977:179;14957:199;;14592:615;;;:::o;20239:100::-;20293:13;20326:5;20319:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20239:100;:::o;88810:105::-;49034:12;:10;:12::i;:::-;49023:23;;:7;:5;:7::i;:::-;:23;;;49015:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;88903:4:::1;;88887:13;:20;;;;;;;:::i;:::-;;88810:105:::0;;:::o;22185:204::-;22253:7;22278:16;22286:7;22278;:16::i;:::-;22273:64;;22303:34;;;;;;;;;;;;;;22273:64;22357:15;:24;22373:7;22357:24;;;;;;;;;;;;;;;;;;;;;22350:31;;22185:204;;;:::o;21733:386::-;21806:13;21822:16;21830:7;21822;:16::i;:::-;21806:32;;21878:5;21855:28;;:19;:17;:19::i;:::-;:28;;;21851:175;;21903:44;21920:5;21927:19;:17;:19::i;:::-;21903:16;:44::i;:::-;21898:128;;21975:35;;;;;;;;;;;;;;21898:128;21851:175;22065:2;22038:15;:24;22054:7;22038:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;22103:7;22099:2;22083:28;;22092:5;22083:28;;;;;;;;;;;;21795:324;21733:386;;:::o;13646:315::-;13699:7;13927:15;:13;:15::i;:::-;13912:12;;13896:13;;:28;:46;13889:53;;13646:315;:::o;31450:2800::-;31584:27;31614;31633:7;31614:18;:27::i;:::-;31584:57;;31699:4;31658:45;;31674:19;31658:45;;;31654:86;;31712:28;;;;;;;;;;;;;;31654:86;31754:27;31783:23;31810:28;31830:7;31810:19;:28::i;:::-;31753:85;;;;31938:62;31957:15;31974:4;31980:19;:17;:19::i;:::-;31938:18;:62::i;:::-;31933:174;;32020:43;32037:4;32043:19;:17;:19::i;:::-;32020:16;:43::i;:::-;32015:92;;32072:35;;;;;;;;;;;;;;32015:92;31933:174;32138:1;32124:16;;:2;:16;;;32120:52;;32149:23;;;;;;;;;;;;;;32120:52;32185:43;32207:4;32213:2;32217:7;32226:1;32185:21;:43::i;:::-;32321:15;32318:160;;;32461:1;32440:19;32433:30;32318:160;32856:18;:24;32875:4;32856:24;;;;;;;;;;;;;;;;32854:26;;;;;;;;;;;;32925:18;:22;32944:2;32925:22;;;;;;;;;;;;;;;;32923:24;;;;;;;;;;;33247:145;33284:2;33332:45;33347:4;33353:2;33357:19;33332:14;:45::i;:::-;10874:8;33305:72;33247:18;:145::i;:::-;33218:17;:26;33236:7;33218:26;;;;;;;;;;;:174;;;;33562:1;10874:8;33512:19;:46;:51;33508:626;;33584:19;33616:1;33606:7;:11;33584:33;;33773:1;33739:17;:30;33757:11;33739:30;;;;;;;;;;;;:35;33735:384;;33877:13;;33862:11;:28;33858:242;;34057:19;34024:17;:30;34042:11;34024:30;;;;;;;;;;;:52;;;;33858:242;33735:384;33565:569;33508:626;34181:7;34177:2;34162:27;;34171:4;34162:27;;;;;;;;;;;;34200:42;34221:4;34227:2;34231:7;34240:1;34200:20;:42::i;:::-;31573:2677;;;31450:2800;;;:::o;87398:49::-;87444:3;87398:49;:::o;91107:469::-;91164:7;88367:15;88353:29;;;;;;;;:::i;:::-;;:10;;;;;;;;;;;:29;;;;;;;;:::i;:::-;;;88345:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;88434:1;88424:7;:11;88416:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;88514:10;;88503:7;88487:13;:11;:13::i;:::-;:23;;;;:::i;:::-;:37;;88479:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;88225:10:::1;88212:23;;:9;:23;;;88204:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;91223:17:::2;91209:31;;;;;;;;:::i;:::-;;:10;;;;;;;;;;;:31;;;;;;;;:::i;:::-;;;91201:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;87570:2;91317:7;91286:16;:28;91303:10;91286:28;;;;;;;;;;;;;;;;:38;;;;:::i;:::-;:68;;91278:116;;;;;;;;;;;;:::i;:::-;;;;;;;;;91440:7;91426:11;;:21;;;;:::i;:::-;91413:9;:34;91405:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;91520:7;91488:16;:28;91505:10;91488:28;;;;;;;;;;;;;;;;:39;;;;;;;:::i;:::-;;;;;;;;91538:30;91548:10;91560:7;91538:9;:30::i;:::-;91107:469:::0;;:::o;91584:307::-;91644:7;88367:15;88353:29;;;;;;;;:::i;:::-;;:10;;;;;;;;;;;:29;;;;;;;;:::i;:::-;;;88345:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;88434:1;88424:7;:11;88416:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;88514:10;;88503:7;88487:13;:11;:13::i;:::-;:23;;;;:::i;:::-;:37;;88479:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;88225:10:::1;88212:23;;:9;:23;;;88204:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;91703:20:::2;91689:34:::0;::::2;;;;;;;:::i;:::-;;:10;;;;;;;;;;;:34;;;;;;;;:::i;:::-;;;91681:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;91805:7;91788:14;;:24;;;;:::i;:::-;91775:9;:37;91767:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;91853:30;91863:10;91875:7;91853:9;:30::i;:::-;91584:307:::0;;:::o;91899:152::-;49034:12;:10;:12::i;:::-;49023:23;;:7;:5;:7::i;:::-;:23;;;49015:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;91949:15:::1;91967:21;91949:39;;91999:44;92025:7;:5;:7::i;:::-;92035;91999:17;:44::i;:::-;91938:113;91899:152::o:0;23075:185::-;23213:39;23230:4;23236:2;23240:7;23213:39;;;;;;;;;;;;:16;:39::i;:::-;23075:185;;;:::o;87862:49::-;;;;;;;;;;;;;;;;;:::o;89267:119::-;49034:12;:10;:12::i;:::-;49023:23;;:7;:5;:7::i;:::-;:23;;;49015:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;89362:16:::1;89349:10;;:29;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;89267:119:::0;:::o;88702:100::-;49034:12;:10;:12::i;:::-;49023:23;;:7;:5;:7::i;:::-;:23;;;49015:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;88790:4:::1;;88774:13;:20;;;;;;;:::i;:::-;;88702:100:::0;;:::o;20028:144::-;20092:7;20135:27;20154:7;20135:18;:27::i;:::-;20112:52;;20028:144;;;:::o;15271:224::-;15335:7;15376:1;15359:19;;:5;:19;;;15355:60;;15387:28;;;;;;;;;;;;;;15355:60;9826:13;15433:18;:25;15452:5;15433:25;;;;;;;;;;;;;;;;:54;15426:61;;15271:224;;;:::o;49454:103::-;49034:12;:10;:12::i;:::-;49023:23;;:7;:5;:7::i;:::-;:23;;;49015:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;49519:30:::1;49546:1;49519:18;:30::i;:::-;49454:103::o:0;87807:48::-;;;;;;;;;;;;;;;;;:::o;87454:56::-;87508:2;87454:56;:::o;87579:41::-;;;;:::o;48803:87::-;48849:7;48876:6;;;;;;;;;;;48869:13;;48803:87;:::o;20408:104::-;20464:13;20497:7;20490:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20408:104;:::o;22461:308::-;22572:19;:17;:19::i;:::-;22560:31;;:8;:31;;;22556:61;;22600:17;;;;;;;;;;;;;;22556:61;22682:8;22630:18;:39;22649:19;:17;:19::i;:::-;22630:39;;;;;;;;;;;;;;;:49;22670:8;22630:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;22742:8;22706:55;;22721:19;:17;:19::i;:::-;22706:55;;;22752:8;22706:55;;;;;;:::i;:::-;;;;;;;;22461:308;;:::o;89188:71::-;49034:12;:10;:12::i;:::-;49023:23;;:7;:5;:7::i;:::-;:23;;;49015:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;89247:4:::1;89236:8;;:15;;;;;;;;;;;;;;;;;;89188:71::o:0;87637:40::-;;;;:::o;87918:48::-;;;;;;;;;;;;;;;;;:::o;90394:705::-;90452:7;88367:15;88353:29;;;;;;;;:::i;:::-;;:10;;;;;;;;;;;:29;;;;;;;;:::i;:::-;;;88345:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;88434:1;88424:7;:11;88416:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;88514:10;;88503:7;88487:13;:11;:13::i;:::-;:23;;;;:::i;:::-;:37;;88479:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;88225:10:::1;88212:23;;:9;:23;;;88204:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;90511:18:::2;90497:32;;;;;;;;:::i;:::-;;:10;;;;;;;;;;;:32;;;;;;;;:::i;:::-;;;90489:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;90569:12;90584:16;:28;90601:10;90584:28;;;;;;;;;;;;;;;;90569:43;;90641:1;90631:7;:11;90623:40;;;;;;;;;;;;:::i;:::-;;;;;;;;;90693:7;90682;:18;;90674:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;87508:2;90787:7;90755:17;:29;90773:10;90755:29;;;;;;;;;;;;;;;;:39;;;;:::i;:::-;:70;;90747:118;;;;;;;;;;;;:::i;:::-;;;;;;;;;90912:7;90897:12;;:22;;;;:::i;:::-;90884:9;:35;90876:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;90992:7;90960:16;:28;90977:10;90960:28;;;;;;;;;;;;;;;;:39;;;;;;;:::i;:::-;;;;;;;;91043:7;91010:17;:29;91028:10;91010:29;;;;;;;;;;;;;;;;:40;;;;;;;:::i;:::-;;;;;;;;91061:30;91071:10;91083:7;91061:9;:30::i;:::-;90478:621;90394:705:::0;;:::o;89394:335::-;49034:12;:10;:12::i;:::-;49023:23;;:7;:5;:7::i;:::-;:23;;;49015:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;89512:9:::1;89507:215;89531:9;;:16;;89527:1;:20;89507:215;;;87508:2;89577:6;;89584:1;89577:9;;;;;;;:::i;:::-;;;;;;;;:40;;89569:84;;;;;;;;;;;;:::i;:::-;;;;;;;;;89701:6;;89708:1;89701:9;;;;;;;:::i;:::-;;;;;;;;89668:16;:30;89685:9;;89695:1;89685:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;89668:30;;;;;;;;;;;;;;;:42;;;;89549:3;;;;;:::i;:::-;;;;89507:215;;;;89394:335:::0;;;;:::o;23331:399::-;23498:31;23511:4;23517:2;23521:7;23498:12;:31::i;:::-;23562:1;23544:2;:14;;;:19;23540:183;;23583:56;23614:4;23620:2;23624:7;23633:5;23583:30;:56::i;:::-;23578:145;;23667:40;;;;;;;;;;;;;;23578:145;23540:183;23331:399;;;;:::o;87517:55::-;87570:2;87517:55;:::o;88923:257::-;88996:13;89026:22;89040:7;89026:13;:22::i;:::-;89021:65;;89057:29;;;;;;;;;;;;;;89021:65;89101:8;;;;;;;;;;;89097:34;;89118:13;89111:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89097:34;89149:23;89164:7;89149:14;:23::i;:::-;89142:30;;88923:257;;;;:::o;89772:210::-;49034:12;:10;:12::i;:::-;49023:23;;:7;:5;:7::i;:::-;:23;;;49015:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;89869:9:::1;89864:111;89888:9;;:16;;89884:1;:20;89864:111;;;89933:16;:30;89950:9;;89960:1;89950:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;89933:30;;;;;;;;;;;;;;;89926:37;;;89906:3;;;;;:::i;:::-;;;;89864:111;;;;89772:210:::0;;:::o;22840:164::-;22937:4;22961:18;:25;22980:5;22961:25;;;;;;;;;;;;;;;:35;22987:8;22961:35;;;;;;;;;;;;;;;;;;;;;;;;;22954:42;;22840:164;;;;:::o;49712:201::-;49034:12;:10;:12::i;:::-;49023:23;;:7;:5;:7::i;:::-;:23;;;49015:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;49821:1:::1;49801:22;;:8;:22;;::::0;49793:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;49877:28;49896:8;49877:18;:28::i;:::-;49712:201:::0;:::o;87358:33::-;;;;:::o;90026:164::-;49034:12;:10;:12::i;:::-;49023:23;;:7;:5;:7::i;:::-;:23;;;49015:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;90127:12:::1;90113:11;:26;;;;90167:15;90150:14;:32;;;;90026:164:::0;;:::o;87754:46::-;;;;;;;;;;;;;:::o;47527:98::-;47580:7;47607:10;47600:17;;47527:98;:::o;23985:273::-;24042:4;24098:7;24079:15;:13;:15::i;:::-;:26;;:66;;;;;24132:13;;24122:7;:23;24079:66;:152;;;;;24230:1;10596:8;24183:17;:26;24201:7;24183:26;;;;;;;;;;;;:43;:48;24079:152;24059:172;;23985:273;;;:::o;42546:105::-;42606:7;42633:10;42626:17;;42546:105;:::o;13170:92::-;13226:7;13170:92;:::o;16945:1129::-;17012:7;17032:12;17047:7;17032:22;;17115:4;17096:15;:13;:15::i;:::-;:23;17092:915;;17149:13;;17142:4;:20;17138:869;;;17187:14;17204:17;:23;17222:4;17204:23;;;;;;;;;;;;17187:40;;17320:1;10596:8;17293:6;:23;:28;17289:699;;17812:113;17829:1;17819:6;:11;17812:113;;17872:17;:25;17890:6;;;;;;;17872:25;;;;;;;;;;;;17863:34;;17812:113;;;17958:6;17951:13;;;;;;17289:699;17164:843;17138:869;17092:915;18035:31;;;;;;;;;;;;;;16945:1129;;;;:::o;29786:652::-;29881:27;29910:23;29951:53;30007:15;29951:71;;30193:7;30187:4;30180:21;30228:22;30222:4;30215:36;30304:4;30298;30288:21;30265:44;;30400:19;30394:26;30375:45;;30131:300;29786:652;;;:::o;30551:645::-;30693:11;30855:15;30849:4;30845:26;30837:34;;31014:15;31003:9;30999:31;30986:44;;31161:15;31150:9;31147:30;31140:4;31129:9;31126:19;31123:55;31113:65;;30551:645;;;;;:::o;41379:159::-;;;;;:::o;39691:309::-;39826:7;39846:16;10997:3;39872:19;:40;;39846:67;;10997:3;39939:31;39950:4;39956:2;39960:9;39939:10;:31::i;:::-;39931:40;;:61;;39924:68;;;39691:309;;;;;:::o;19519:447::-;19599:14;19767:15;19760:5;19756:27;19747:36;;19941:5;19927:11;19903:22;19899:40;19896:51;19889:5;19886:62;19876:72;;19519:447;;;;:::o;42197:158::-;;;;;:::o;24342:104::-;24411:27;24421:2;24425:8;24411:27;;;;;;;;;;;;:9;:27::i;:::-;24342:104;;:::o;52765:317::-;52880:6;52855:21;:31;;52847:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;52934:12;52952:9;:14;;52974:6;52952:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52933:52;;;53004:7;52996:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;52836:246;52765:317;;:::o;50073:191::-;50147:16;50166:6;;;;;;;;;;;50147:25;;50192:8;50183:6;;:17;;;;;;;;;;;;;;;;;;50247:8;50216:40;;50237:8;50216:40;;;;;;;;;;;;50136:128;50073:191;:::o;38201:716::-;38364:4;38410:2;38385:45;;;38431:19;:17;:19::i;:::-;38452:4;38458:7;38467:5;38385:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;38381:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38685:1;38668:6;:13;:18;38664:235;;38714:40;;;;;;;;;;;;;;38664:235;38857:6;38851:13;38842:6;38838:2;38834:15;38827:38;38381:529;38554:54;;;38544:64;;;:6;:64;;;;38537:71;;;38201:716;;;;;;:::o;20583:318::-;20656:13;20687:16;20695:7;20687;:16::i;:::-;20682:59;;20712:29;;;;;;;;;;;;;;20682:59;20754:21;20778:10;:8;:10::i;:::-;20754:34;;20831:1;20812:7;20806:21;:26;:87;;;;;;;;;;;;;;;;;20859:7;20868:18;20878:7;20868:9;:18::i;:::-;20842:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;20806:87;20799:94;;;20583:318;;;:::o;40576:147::-;40713:6;40576:147;;;;;:::o;24862:681::-;24985:19;24991:2;24995:8;24985:5;:19::i;:::-;25064:1;25046:2;:14;;;:19;25042:483;;25086:11;25100:13;;25086:27;;25132:13;25154:8;25148:3;:14;25132:30;;25181:233;25212:62;25251:1;25255:2;25259:7;;;;;;25268:5;25212:30;:62::i;:::-;25207:167;;25310:40;;;;;;;;;;;;;;25207:167;25409:3;25401:5;:11;25181:233;;25496:3;25479:13;;:20;25475:34;;25501:8;;;25475:34;25067:458;;25042:483;24862:681;;;:::o;88588:106::-;88640:13;88673;88666:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88588:106;:::o;42757:1960::-;42814:17;43233:3;43226:4;43220:11;43216:21;43209:28;;43324:3;43318:4;43311:17;43430:3;43886:5;44016:1;44011:3;44007:11;44000:18;;44153:2;44147:4;44143:13;44139:2;44135:22;44130:3;44122:36;44194:2;44188:4;44184:13;44176:21;;43778:697;44213:4;43778:697;;;44404:1;44399:3;44395:11;44388:18;;44455:2;44449:4;44445:13;44441:2;44437:22;44432:3;44424:36;44308:2;44302:4;44298:13;44290:21;;43778:697;;;43782:430;44514:3;44509;44505:13;44629:2;44624:3;44620:12;44613:19;;44692:6;44687:3;44680:19;42853:1857;;42757:1960;;;:::o;25816:1529::-;25881:20;25904:13;;25881:36;;25946:1;25932:16;;:2;:16;;;25928:48;;25957:19;;;;;;;;;;;;;;25928:48;26003:1;25991:8;:13;25987:44;;26013:18;;;;;;;;;;;;;;25987:44;26044:61;26074:1;26078:2;26082:12;26096:8;26044:21;:61::i;:::-;26587:1;9963:2;26558:1;:25;;26557:31;26545:8;:44;26519:18;:22;26538:2;26519:22;;;;;;;;;;;;;;;;:70;;;;;;;;;;;26866:139;26903:2;26957:33;26980:1;26984:2;26988:1;26957:14;:33::i;:::-;26924:30;26945:8;26924:20;:30::i;:::-;:66;26866:18;:139::i;:::-;26832:17;:31;26850:12;26832:31;;;;;;;;;;;:173;;;;27022:15;27040:12;27022:30;;27067:11;27096:8;27081:12;:23;27067:37;;27119:101;27171:9;;;;;;27167:2;27146:35;;27163:1;27146:35;;;;;;;;;;;;27215:3;27205:7;:13;27119:101;;27252:3;27236:13;:19;;;;26293:974;;27277:60;27306:1;27310:2;27314:12;27328:8;27277:20;:60::i;:::-;25870:1475;25816:1529;;:::o;21349:322::-;21419:14;21650:1;21640:8;21637:15;21612:23;21608:45;21598:55;;21349:322;;;:::o;7:77:1:-;44:7;73:5;62:16;;7:77;;;:::o;90:118::-;177:24;195:5;177:24;:::i;:::-;172:3;165:37;90:118;;:::o;214:222::-;307:4;345:2;334:9;330:18;322:26;;358:71;426:1;415:9;411:17;402:6;358:71;:::i;:::-;214:222;;;;:::o;442:75::-;475:6;508:2;502:9;492:19;;442:75;:::o;523:117::-;632:1;629;622:12;646:117;755:1;752;745:12;769:149;805:7;845:66;838:5;834:78;823:89;;769:149;;;:::o;924:120::-;996:23;1013:5;996:23;:::i;:::-;989:5;986:34;976:62;;1034:1;1031;1024:12;976:62;924:120;:::o;1050:137::-;1095:5;1133:6;1120:20;1111:29;;1149:32;1175:5;1149:32;:::i;:::-;1050:137;;;;:::o;1193:327::-;1251:6;1300:2;1288:9;1279:7;1275:23;1271:32;1268:119;;;1306:79;;:::i;:::-;1268:119;1426:1;1451:52;1495:7;1486:6;1475:9;1471:22;1451:52;:::i;:::-;1441:62;;1397:116;1193:327;;;;:::o;1526:90::-;1560:7;1603:5;1596:13;1589:21;1578:32;;1526:90;;;:::o;1622:109::-;1703:21;1718:5;1703:21;:::i;:::-;1698:3;1691:34;1622:109;;:::o;1737:210::-;1824:4;1862:2;1851:9;1847:18;1839:26;;1875:65;1937:1;1926:9;1922:17;1913:6;1875:65;:::i;:::-;1737:210;;;;:::o;1953:99::-;2005:6;2039:5;2033:12;2023:22;;1953:99;;;:::o;2058:169::-;2142:11;2176:6;2171:3;2164:19;2216:4;2211:3;2207:14;2192:29;;2058:169;;;;:::o;2233:246::-;2314:1;2324:113;2338:6;2335:1;2332:13;2324:113;;;2423:1;2418:3;2414:11;2408:18;2404:1;2399:3;2395:11;2388:39;2360:2;2357:1;2353:10;2348:15;;2324:113;;;2471:1;2462:6;2457:3;2453:16;2446:27;2295:184;2233:246;;;:::o;2485:102::-;2526:6;2577:2;2573:7;2568:2;2561:5;2557:14;2553:28;2543:38;;2485:102;;;:::o;2593:377::-;2681:3;2709:39;2742:5;2709:39;:::i;:::-;2764:71;2828:6;2823:3;2764:71;:::i;:::-;2757:78;;2844:65;2902:6;2897:3;2890:4;2883:5;2879:16;2844:65;:::i;:::-;2934:29;2956:6;2934:29;:::i;:::-;2929:3;2925:39;2918:46;;2685:285;2593:377;;;;:::o;2976:313::-;3089:4;3127:2;3116:9;3112:18;3104:26;;3176:9;3170:4;3166:20;3162:1;3151:9;3147:17;3140:47;3204:78;3277:4;3268:6;3204:78;:::i;:::-;3196:86;;2976:313;;;;:::o;3295:117::-;3404:1;3401;3394:12;3418:117;3527:1;3524;3517:12;3541:117;3650:1;3647;3640:12;3678:553;3736:8;3746:6;3796:3;3789:4;3781:6;3777:17;3773:27;3763:122;;3804:79;;:::i;:::-;3763:122;3917:6;3904:20;3894:30;;3947:18;3939:6;3936:30;3933:117;;;3969:79;;:::i;:::-;3933:117;4083:4;4075:6;4071:17;4059:29;;4137:3;4129:4;4121:6;4117:17;4107:8;4103:32;4100:41;4097:128;;;4144:79;;:::i;:::-;4097:128;3678:553;;;;;:::o;4237:529::-;4308:6;4316;4365:2;4353:9;4344:7;4340:23;4336:32;4333:119;;;4371:79;;:::i;:::-;4333:119;4519:1;4508:9;4504:17;4491:31;4549:18;4541:6;4538:30;4535:117;;;4571:79;;:::i;:::-;4535:117;4684:65;4741:7;4732:6;4721:9;4717:22;4684:65;:::i;:::-;4666:83;;;;4462:297;4237:529;;;;;:::o;4772:122::-;4845:24;4863:5;4845:24;:::i;:::-;4838:5;4835:35;4825:63;;4884:1;4881;4874:12;4825:63;4772:122;:::o;4900:139::-;4946:5;4984:6;4971:20;4962:29;;5000:33;5027:5;5000:33;:::i;:::-;4900:139;;;;:::o;5045:329::-;5104:6;5153:2;5141:9;5132:7;5128:23;5124:32;5121:119;;;5159:79;;:::i;:::-;5121:119;5279:1;5304:53;5349:7;5340:6;5329:9;5325:22;5304:53;:::i;:::-;5294:63;;5250:117;5045:329;;;;:::o;5380:126::-;5417:7;5457:42;5450:5;5446:54;5435:65;;5380:126;;;:::o;5512:96::-;5549:7;5578:24;5596:5;5578:24;:::i;:::-;5567:35;;5512:96;;;:::o;5614:118::-;5701:24;5719:5;5701:24;:::i;:::-;5696:3;5689:37;5614:118;;:::o;5738:222::-;5831:4;5869:2;5858:9;5854:18;5846:26;;5882:71;5950:1;5939:9;5935:17;5926:6;5882:71;:::i;:::-;5738:222;;;;:::o;5966:122::-;6039:24;6057:5;6039:24;:::i;:::-;6032:5;6029:35;6019:63;;6078:1;6075;6068:12;6019:63;5966:122;:::o;6094:139::-;6140:5;6178:6;6165:20;6156:29;;6194:33;6221:5;6194:33;:::i;:::-;6094:139;;;;:::o;6239:474::-;6307:6;6315;6364:2;6352:9;6343:7;6339:23;6335:32;6332:119;;;6370:79;;:::i;:::-;6332:119;6490:1;6515:53;6560:7;6551:6;6540:9;6536:22;6515:53;:::i;:::-;6505:63;;6461:117;6617:2;6643:53;6688:7;6679:6;6668:9;6664:22;6643:53;:::i;:::-;6633:63;;6588:118;6239:474;;;;;:::o;6719:619::-;6796:6;6804;6812;6861:2;6849:9;6840:7;6836:23;6832:32;6829:119;;;6867:79;;:::i;:::-;6829:119;6987:1;7012:53;7057:7;7048:6;7037:9;7033:22;7012:53;:::i;:::-;7002:63;;6958:117;7114:2;7140:53;7185:7;7176:6;7165:9;7161:22;7140:53;:::i;:::-;7130:63;;7085:118;7242:2;7268:53;7313:7;7304:6;7293:9;7289:22;7268:53;:::i;:::-;7258:63;;7213:118;6719:619;;;;;:::o;7344:329::-;7403:6;7452:2;7440:9;7431:7;7427:23;7423:32;7420:119;;;7458:79;;:::i;:::-;7420:119;7578:1;7603:53;7648:7;7639:6;7628:9;7624:22;7603:53;:::i;:::-;7593:63;;7549:117;7344:329;;;;:::o;7679:114::-;7767:1;7760:5;7757:12;7747:40;;7783:1;7780;7773:12;7747:40;7679:114;:::o;7799:169::-;7860:5;7898:6;7885:20;7876:29;;7914:48;7956:5;7914:48;:::i;:::-;7799:169;;;;:::o;7974:359::-;8048:6;8097:2;8085:9;8076:7;8072:23;8068:32;8065:119;;;8103:79;;:::i;:::-;8065:119;8223:1;8248:68;8308:7;8299:6;8288:9;8284:22;8248:68;:::i;:::-;8238:78;;8194:132;7974:359;;;;:::o;8339:116::-;8409:21;8424:5;8409:21;:::i;:::-;8402:5;8399:32;8389:60;;8445:1;8442;8435:12;8389:60;8339:116;:::o;8461:133::-;8504:5;8542:6;8529:20;8520:29;;8558:30;8582:5;8558:30;:::i;:::-;8461:133;;;;:::o;8600:468::-;8665:6;8673;8722:2;8710:9;8701:7;8697:23;8693:32;8690:119;;;8728:79;;:::i;:::-;8690:119;8848:1;8873:53;8918:7;8909:6;8898:9;8894:22;8873:53;:::i;:::-;8863:63;;8819:117;8975:2;9001:50;9043:7;9034:6;9023:9;9019:22;9001:50;:::i;:::-;8991:60;;8946:115;8600:468;;;;;:::o;9091:568::-;9164:8;9174:6;9224:3;9217:4;9209:6;9205:17;9201:27;9191:122;;9232:79;;:::i;:::-;9191:122;9345:6;9332:20;9322:30;;9375:18;9367:6;9364:30;9361:117;;;9397:79;;:::i;:::-;9361:117;9511:4;9503:6;9499:17;9487:29;;9565:3;9557:4;9549:6;9545:17;9535:8;9531:32;9528:41;9525:128;;;9572:79;;:::i;:::-;9525:128;9091:568;;;;;:::o;9682:::-;9755:8;9765:6;9815:3;9808:4;9800:6;9796:17;9792:27;9782:122;;9823:79;;:::i;:::-;9782:122;9936:6;9923:20;9913:30;;9966:18;9958:6;9955:30;9952:117;;;9988:79;;:::i;:::-;9952:117;10102:4;10094:6;10090:17;10078:29;;10156:3;10148:4;10140:6;10136:17;10126:8;10122:32;10119:41;10116:128;;;10163:79;;:::i;:::-;10116:128;9682:568;;;;;:::o;10256:934::-;10378:6;10386;10394;10402;10451:2;10439:9;10430:7;10426:23;10422:32;10419:119;;;10457:79;;:::i;:::-;10419:119;10605:1;10594:9;10590:17;10577:31;10635:18;10627:6;10624:30;10621:117;;;10657:79;;:::i;:::-;10621:117;10770:80;10842:7;10833:6;10822:9;10818:22;10770:80;:::i;:::-;10752:98;;;;10548:312;10927:2;10916:9;10912:18;10899:32;10958:18;10950:6;10947:30;10944:117;;;10980:79;;:::i;:::-;10944:117;11093:80;11165:7;11156:6;11145:9;11141:22;11093:80;:::i;:::-;11075:98;;;;10870:313;10256:934;;;;;;;:::o;11196:117::-;11305:1;11302;11295:12;11319:180;11367:77;11364:1;11357:88;11464:4;11461:1;11454:15;11488:4;11485:1;11478:15;11505:281;11588:27;11610:4;11588:27;:::i;:::-;11580:6;11576:40;11718:6;11706:10;11703:22;11682:18;11670:10;11667:34;11664:62;11661:88;;;11729:18;;:::i;:::-;11661:88;11769:10;11765:2;11758:22;11548:238;11505:281;;:::o;11792:129::-;11826:6;11853:20;;:::i;:::-;11843:30;;11882:33;11910:4;11902:6;11882:33;:::i;:::-;11792:129;;;:::o;11927:307::-;11988:4;12078:18;12070:6;12067:30;12064:56;;;12100:18;;:::i;:::-;12064:56;12138:29;12160:6;12138:29;:::i;:::-;12130:37;;12222:4;12216;12212:15;12204:23;;11927:307;;;:::o;12240:146::-;12337:6;12332:3;12327;12314:30;12378:1;12369:6;12364:3;12360:16;12353:27;12240:146;;;:::o;12392:423::-;12469:5;12494:65;12510:48;12551:6;12510:48;:::i;:::-;12494:65;:::i;:::-;12485:74;;12582:6;12575:5;12568:21;12620:4;12613:5;12609:16;12658:3;12649:6;12644:3;12640:16;12637:25;12634:112;;;12665:79;;:::i;:::-;12634:112;12755:54;12802:6;12797:3;12792;12755:54;:::i;:::-;12475:340;12392:423;;;;;:::o;12834:338::-;12889:5;12938:3;12931:4;12923:6;12919:17;12915:27;12905:122;;12946:79;;:::i;:::-;12905:122;13063:6;13050:20;13088:78;13162:3;13154:6;13147:4;13139:6;13135:17;13088:78;:::i;:::-;13079:87;;12895:277;12834:338;;;;:::o;13178:943::-;13273:6;13281;13289;13297;13346:3;13334:9;13325:7;13321:23;13317:33;13314:120;;;13353:79;;:::i;:::-;13314:120;13473:1;13498:53;13543:7;13534:6;13523:9;13519:22;13498:53;:::i;:::-;13488:63;;13444:117;13600:2;13626:53;13671:7;13662:6;13651:9;13647:22;13626:53;:::i;:::-;13616:63;;13571:118;13728:2;13754:53;13799:7;13790:6;13779:9;13775:22;13754:53;:::i;:::-;13744:63;;13699:118;13884:2;13873:9;13869:18;13856:32;13915:18;13907:6;13904:30;13901:117;;;13937:79;;:::i;:::-;13901:117;14042:62;14096:7;14087:6;14076:9;14072:22;14042:62;:::i;:::-;14032:72;;13827:287;13178:943;;;;;;;:::o;14127:559::-;14213:6;14221;14270:2;14258:9;14249:7;14245:23;14241:32;14238:119;;;14276:79;;:::i;:::-;14238:119;14424:1;14413:9;14409:17;14396:31;14454:18;14446:6;14443:30;14440:117;;;14476:79;;:::i;:::-;14440:117;14589:80;14661:7;14652:6;14641:9;14637:22;14589:80;:::i;:::-;14571:98;;;;14367:312;14127:559;;;;;:::o;14692:474::-;14760:6;14768;14817:2;14805:9;14796:7;14792:23;14788:32;14785:119;;;14823:79;;:::i;:::-;14785:119;14943:1;14968:53;15013:7;15004:6;14993:9;14989:22;14968:53;:::i;:::-;14958:63;;14914:117;15070:2;15096:53;15141:7;15132:6;15121:9;15117:22;15096:53;:::i;:::-;15086:63;;15041:118;14692:474;;;;;:::o;15172:::-;15240:6;15248;15297:2;15285:9;15276:7;15272:23;15268:32;15265:119;;;15303:79;;:::i;:::-;15265:119;15423:1;15448:53;15493:7;15484:6;15473:9;15469:22;15448:53;:::i;:::-;15438:63;;15394:117;15550:2;15576:53;15621:7;15612:6;15601:9;15597:22;15576:53;:::i;:::-;15566:63;;15521:118;15172:474;;;;;:::o;15652:180::-;15700:77;15697:1;15690:88;15797:4;15794:1;15787:15;15821:4;15818:1;15811:15;15838:120;15926:1;15919:5;15916:12;15906:46;;15932:18;;:::i;:::-;15906:46;15838:120;:::o;15964:141::-;16016:7;16045:5;16034:16;;16051:48;16093:5;16051:48;:::i;:::-;15964:141;;;:::o;16111:::-;16174:9;16207:39;16240:5;16207:39;:::i;:::-;16194:52;;16111:141;;;:::o;16258:157::-;16358:50;16402:5;16358:50;:::i;:::-;16353:3;16346:63;16258:157;;:::o;16421:248::-;16527:4;16565:2;16554:9;16550:18;16542:26;;16578:84;16659:1;16648:9;16644:17;16635:6;16578:84;:::i;:::-;16421:248;;;;:::o;16675:180::-;16723:77;16720:1;16713:88;16820:4;16817:1;16810:15;16844:4;16841:1;16834:15;16861:320;16905:6;16942:1;16936:4;16932:12;16922:22;;16989:1;16983:4;16979:12;17010:18;17000:81;;17066:4;17058:6;17054:17;17044:27;;17000:81;17128:2;17120:6;17117:14;17097:18;17094:38;17091:84;;17147:18;;:::i;:::-;17091:84;16912:269;16861:320;;;:::o;17187:182::-;17327:34;17323:1;17315:6;17311:14;17304:58;17187:182;:::o;17375:366::-;17517:3;17538:67;17602:2;17597:3;17538:67;:::i;:::-;17531:74;;17614:93;17703:3;17614:93;:::i;:::-;17732:2;17727:3;17723:12;17716:19;;17375:366;;;:::o;17747:419::-;17913:4;17951:2;17940:9;17936:18;17928:26;;18000:9;17994:4;17990:20;17986:1;17975:9;17971:17;17964:47;18028:131;18154:4;18028:131;:::i;:::-;18020:139;;17747:419;;;:::o;18172:97::-;18231:6;18259:3;18249:13;;18172:97;;;;:::o;18275:141::-;18324:4;18347:3;18339:11;;18370:3;18367:1;18360:14;18404:4;18401:1;18391:18;18383:26;;18275:141;;;:::o;18422:93::-;18459:6;18506:2;18501;18494:5;18490:14;18486:23;18476:33;;18422:93;;;:::o;18521:107::-;18565:8;18615:5;18609:4;18605:16;18584:37;;18521:107;;;;:::o;18634:393::-;18703:6;18753:1;18741:10;18737:18;18776:97;18806:66;18795:9;18776:97;:::i;:::-;18894:39;18924:8;18913:9;18894:39;:::i;:::-;18882:51;;18966:4;18962:9;18955:5;18951:21;18942:30;;19015:4;19005:8;19001:19;18994:5;18991:30;18981:40;;18710:317;;18634:393;;;;;:::o;19033:60::-;19061:3;19082:5;19075:12;;19033:60;;;:::o;19099:142::-;19149:9;19182:53;19200:34;19209:24;19227:5;19209:24;:::i;:::-;19200:34;:::i;:::-;19182:53;:::i;:::-;19169:66;;19099:142;;;:::o;19247:75::-;19290:3;19311:5;19304:12;;19247:75;;;:::o;19328:269::-;19438:39;19469:7;19438:39;:::i;:::-;19499:91;19548:41;19572:16;19548:41;:::i;:::-;19540:6;19533:4;19527:11;19499:91;:::i;:::-;19493:4;19486:105;19404:193;19328:269;;;:::o;19603:73::-;19648:3;19603:73;:::o;19682:189::-;19759:32;;:::i;:::-;19800:65;19858:6;19850;19844:4;19800:65;:::i;:::-;19735:136;19682:189;;:::o;19877:186::-;19937:120;19954:3;19947:5;19944:14;19937:120;;;20008:39;20045:1;20038:5;20008:39;:::i;:::-;19981:1;19974:5;19970:13;19961:22;;19937:120;;;19877:186;;:::o;20069:543::-;20170:2;20165:3;20162:11;20159:446;;;20204:38;20236:5;20204:38;:::i;:::-;20288:29;20306:10;20288:29;:::i;:::-;20278:8;20274:44;20471:2;20459:10;20456:18;20453:49;;;20492:8;20477:23;;20453:49;20515:80;20571:22;20589:3;20571:22;:::i;:::-;20561:8;20557:37;20544:11;20515:80;:::i;:::-;20174:431;;20159:446;20069:543;;;:::o;20618:117::-;20672:8;20722:5;20716:4;20712:16;20691:37;;20618:117;;;;:::o;20741:169::-;20785:6;20818:51;20866:1;20862:6;20854:5;20851:1;20847:13;20818:51;:::i;:::-;20814:56;20899:4;20893;20889:15;20879:25;;20792:118;20741:169;;;;:::o;20915:295::-;20991:4;21137:29;21162:3;21156:4;21137:29;:::i;:::-;21129:37;;21199:3;21196:1;21192:11;21186:4;21183:21;21175:29;;20915:295;;;;:::o;21215:1403::-;21339:44;21379:3;21374;21339:44;:::i;:::-;21448:18;21440:6;21437:30;21434:56;;;21470:18;;:::i;:::-;21434:56;21514:38;21546:4;21540:11;21514:38;:::i;:::-;21599:67;21659:6;21651;21645:4;21599:67;:::i;:::-;21693:1;21722:2;21714:6;21711:14;21739:1;21734:632;;;;22410:1;22427:6;22424:84;;;22483:9;22478:3;22474:19;22461:33;22452:42;;22424:84;22534:67;22594:6;22587:5;22534:67;:::i;:::-;22528:4;22521:81;22383:229;21704:908;;21734:632;21786:4;21782:9;21774:6;21770:22;21820:37;21852:4;21820:37;:::i;:::-;21879:1;21893:215;21907:7;21904:1;21901:14;21893:215;;;21993:9;21988:3;21984:19;21971:33;21963:6;21956:49;22044:1;22036:6;22032:14;22022:24;;22091:2;22080:9;22076:18;22063:31;;21930:4;21927:1;21923:12;21918:17;;21893:215;;;22136:6;22127:7;22124:19;22121:186;;;22201:9;22196:3;22192:19;22179:33;22244:48;22286:4;22278:6;22274:17;22263:9;22244:48;:::i;:::-;22236:6;22229:64;22144:163;22121:186;22353:1;22349;22341:6;22337:14;22333:22;22327:4;22320:36;21741:625;;;21704:908;;21314:1304;;;21215:1403;;;:::o;22624:168::-;22764:20;22760:1;22752:6;22748:14;22741:44;22624:168;:::o;22798:366::-;22940:3;22961:67;23025:2;23020:3;22961:67;:::i;:::-;22954:74;;23037:93;23126:3;23037:93;:::i;:::-;23155:2;23150:3;23146:12;23139:19;;22798:366;;;:::o;23170:419::-;23336:4;23374:2;23363:9;23359:18;23351:26;;23423:9;23417:4;23413:20;23409:1;23398:9;23394:17;23387:47;23451:131;23577:4;23451:131;:::i;:::-;23443:139;;23170:419;;;:::o;23595:178::-;23735:30;23731:1;23723:6;23719:14;23712:54;23595:178;:::o;23779:366::-;23921:3;23942:67;24006:2;24001:3;23942:67;:::i;:::-;23935:74;;24018:93;24107:3;24018:93;:::i;:::-;24136:2;24131:3;24127:12;24120:19;;23779:366;;;:::o;24151:419::-;24317:4;24355:2;24344:9;24340:18;24332:26;;24404:9;24398:4;24394:20;24390:1;24379:9;24375:17;24368:47;24432:131;24558:4;24432:131;:::i;:::-;24424:139;;24151:419;;;:::o;24576:180::-;24624:77;24621:1;24614:88;24721:4;24718:1;24711:15;24745:4;24742:1;24735:15;24762:191;24802:3;24821:20;24839:1;24821:20;:::i;:::-;24816:25;;24855:20;24873:1;24855:20;:::i;:::-;24850:25;;24898:1;24895;24891:9;24884:16;;24919:3;24916:1;24913:10;24910:36;;;24926:18;;:::i;:::-;24910:36;24762:191;;;;:::o;24959:181::-;25099:33;25095:1;25087:6;25083:14;25076:57;24959:181;:::o;25146:366::-;25288:3;25309:67;25373:2;25368:3;25309:67;:::i;:::-;25302:74;;25385:93;25474:3;25385:93;:::i;:::-;25503:2;25498:3;25494:12;25487:19;;25146:366;;;:::o;25518:419::-;25684:4;25722:2;25711:9;25707:18;25699:26;;25771:9;25765:4;25761:20;25757:1;25746:9;25742:17;25735:47;25799:131;25925:4;25799:131;:::i;:::-;25791:139;;25518:419;;;:::o;25943:222::-;26083:34;26079:1;26071:6;26067:14;26060:58;26152:5;26147:2;26139:6;26135:15;26128:30;25943:222;:::o;26171:366::-;26313:3;26334:67;26398:2;26393:3;26334:67;:::i;:::-;26327:74;;26410:93;26499:3;26410:93;:::i;:::-;26528:2;26523:3;26519:12;26512:19;;26171:366;;;:::o;26543:419::-;26709:4;26747:2;26736:9;26732:18;26724:26;;26796:9;26790:4;26786:20;26782:1;26771:9;26767:17;26760:47;26824:131;26950:4;26824:131;:::i;:::-;26816:139;;26543:419;;;:::o;26968:172::-;27108:24;27104:1;27096:6;27092:14;27085:48;26968:172;:::o;27146:366::-;27288:3;27309:67;27373:2;27368:3;27309:67;:::i;:::-;27302:74;;27385:93;27474:3;27385:93;:::i;:::-;27503:2;27498:3;27494:12;27487:19;;27146:366;;;:::o;27518:419::-;27684:4;27722:2;27711:9;27707:18;27699:26;;27771:9;27765:4;27761:20;27757:1;27746:9;27742:17;27735:47;27799:131;27925:4;27799:131;:::i;:::-;27791:139;;27518:419;;;:::o;27943:222::-;28083:34;28079:1;28071:6;28067:14;28060:58;28152:5;28147:2;28139:6;28135:15;28128:30;27943:222;:::o;28171:366::-;28313:3;28334:67;28398:2;28393:3;28334:67;:::i;:::-;28327:74;;28410:93;28499:3;28410:93;:::i;:::-;28528:2;28523:3;28519:12;28512:19;;28171:366;;;:::o;28543:419::-;28709:4;28747:2;28736:9;28732:18;28724:26;;28796:9;28790:4;28786:20;28782:1;28771:9;28767:17;28760:47;28824:131;28950:4;28824:131;:::i;:::-;28816:139;;28543:419;;;:::o;28968:410::-;29008:7;29031:20;29049:1;29031:20;:::i;:::-;29026:25;;29065:20;29083:1;29065:20;:::i;:::-;29060:25;;29120:1;29117;29113:9;29142:30;29160:11;29142:30;:::i;:::-;29131:41;;29321:1;29312:7;29308:15;29305:1;29302:22;29282:1;29275:9;29255:83;29232:139;;29351:18;;:::i;:::-;29232:139;29016:362;28968:410;;;;:::o;29384:173::-;29524:25;29520:1;29512:6;29508:14;29501:49;29384:173;:::o;29563:366::-;29705:3;29726:67;29790:2;29785:3;29726:67;:::i;:::-;29719:74;;29802:93;29891:3;29802:93;:::i;:::-;29920:2;29915:3;29911:12;29904:19;;29563:366;;;:::o;29935:419::-;30101:4;30139:2;30128:9;30124:18;30116:26;;30188:9;30182:4;30178:20;30174:1;30163:9;30159:17;30152:47;30216:131;30342:4;30216:131;:::i;:::-;30208:139;;29935:419;;;:::o;30360:178::-;30500:30;30496:1;30488:6;30484:14;30477:54;30360:178;:::o;30544:366::-;30686:3;30707:67;30771:2;30766:3;30707:67;:::i;:::-;30700:74;;30783:93;30872:3;30783:93;:::i;:::-;30901:2;30896:3;30892:12;30885:19;;30544:366;;;:::o;30916:419::-;31082:4;31120:2;31109:9;31105:18;31097:26;;31169:9;31163:4;31159:20;31155:1;31144:9;31140:17;31133:47;31197:131;31323:4;31197:131;:::i;:::-;31189:139;;30916:419;;;:::o;31341:173::-;31481:25;31477:1;31469:6;31465:14;31458:49;31341:173;:::o;31520:366::-;31662:3;31683:67;31747:2;31742:3;31683:67;:::i;:::-;31676:74;;31759:93;31848:3;31759:93;:::i;:::-;31877:2;31872:3;31868:12;31861:19;;31520:366;;;:::o;31892:419::-;32058:4;32096:2;32085:9;32081:18;32073:26;;32145:9;32139:4;32135:20;32131:1;32120:9;32116:17;32109:47;32173:131;32299:4;32173:131;:::i;:::-;32165:139;;31892:419;;;:::o;32317:173::-;32457:25;32453:1;32445:6;32441:14;32434:49;32317:173;:::o;32496:366::-;32638:3;32659:67;32723:2;32718:3;32659:67;:::i;:::-;32652:74;;32735:93;32824:3;32735:93;:::i;:::-;32853:2;32848:3;32844:12;32837:19;;32496:366;;;:::o;32868:419::-;33034:4;33072:2;33061:9;33057:18;33049:26;;33121:9;33115:4;33111:20;33107:1;33096:9;33092:17;33085:47;33149:131;33275:4;33149:131;:::i;:::-;33141:139;;32868:419;;;:::o;33293:166::-;33433:18;33429:1;33421:6;33417:14;33410:42;33293:166;:::o;33465:366::-;33607:3;33628:67;33692:2;33687:3;33628:67;:::i;:::-;33621:74;;33704:93;33793:3;33704:93;:::i;:::-;33822:2;33817:3;33813:12;33806:19;;33465:366;;;:::o;33837:419::-;34003:4;34041:2;34030:9;34026:18;34018:26;;34090:9;34084:4;34080:20;34076:1;34065:9;34061:17;34054:47;34118:131;34244:4;34118:131;:::i;:::-;34110:139;;33837:419;;;:::o;34262:181::-;34402:33;34398:1;34390:6;34386:14;34379:57;34262:181;:::o;34449:366::-;34591:3;34612:67;34676:2;34671:3;34612:67;:::i;:::-;34605:74;;34688:93;34777:3;34688:93;:::i;:::-;34806:2;34801:3;34797:12;34790:19;;34449:366;;;:::o;34821:419::-;34987:4;35025:2;35014:9;35010:18;35002:26;;35074:9;35068:4;35064:20;35060:1;35049:9;35045:17;35038:47;35102:131;35228:4;35102:131;:::i;:::-;35094:139;;34821:419;;;:::o;35246:194::-;35286:4;35306:20;35324:1;35306:20;:::i;:::-;35301:25;;35340:20;35358:1;35340:20;:::i;:::-;35335:25;;35384:1;35381;35377:9;35369:17;;35408:1;35402:4;35399:11;35396:37;;;35413:18;;:::i;:::-;35396:37;35246:194;;;;:::o;35446:180::-;35494:77;35491:1;35484:88;35591:4;35588:1;35581:15;35615:4;35612:1;35605:15;35632:181;35772:33;35768:1;35760:6;35756:14;35749:57;35632:181;:::o;35819:366::-;35961:3;35982:67;36046:2;36041:3;35982:67;:::i;:::-;35975:74;;36058:93;36147:3;36058:93;:::i;:::-;36176:2;36171:3;36167:12;36160:19;;35819:366;;;:::o;36191:419::-;36357:4;36395:2;36384:9;36380:18;36372:26;;36444:9;36438:4;36434:20;36430:1;36419:9;36415:17;36408:47;36472:131;36598:4;36472:131;:::i;:::-;36464:139;;36191:419;;;:::o;36616:233::-;36655:3;36678:24;36696:5;36678:24;:::i;:::-;36669:33;;36724:66;36717:5;36714:77;36711:103;;36794:18;;:::i;:::-;36711:103;36841:1;36834:5;36830:13;36823:20;;36616:233;;;:::o;36855:225::-;36995:34;36991:1;36983:6;36979:14;36972:58;37064:8;37059:2;37051:6;37047:15;37040:33;36855:225;:::o;37086:366::-;37228:3;37249:67;37313:2;37308:3;37249:67;:::i;:::-;37242:74;;37325:93;37414:3;37325:93;:::i;:::-;37443:2;37438:3;37434:12;37427:19;;37086:366;;;:::o;37458:419::-;37624:4;37662:2;37651:9;37647:18;37639:26;;37711:9;37705:4;37701:20;37697:1;37686:9;37682:17;37675:47;37739:131;37865:4;37739:131;:::i;:::-;37731:139;;37458:419;;;:::o;37883:179::-;38023:31;38019:1;38011:6;38007:14;38000:55;37883:179;:::o;38068:366::-;38210:3;38231:67;38295:2;38290:3;38231:67;:::i;:::-;38224:74;;38307:93;38396:3;38307:93;:::i;:::-;38425:2;38420:3;38416:12;38409:19;;38068:366;;;:::o;38440:419::-;38606:4;38644:2;38633:9;38629:18;38621:26;;38693:9;38687:4;38683:20;38679:1;38668:9;38664:17;38657:47;38721:131;38847:4;38721:131;:::i;:::-;38713:139;;38440:419;;;:::o;38865:147::-;38966:11;39003:3;38988:18;;38865:147;;;;:::o;39018:114::-;;:::o;39138:398::-;39297:3;39318:83;39399:1;39394:3;39318:83;:::i;:::-;39311:90;;39410:93;39499:3;39410:93;:::i;:::-;39528:1;39523:3;39519:11;39512:18;;39138:398;;;:::o;39542:379::-;39726:3;39748:147;39891:3;39748:147;:::i;:::-;39741:154;;39912:3;39905:10;;39542:379;;;:::o;39927:245::-;40067:34;40063:1;40055:6;40051:14;40044:58;40136:28;40131:2;40123:6;40119:15;40112:53;39927:245;:::o;40178:366::-;40320:3;40341:67;40405:2;40400:3;40341:67;:::i;:::-;40334:74;;40417:93;40506:3;40417:93;:::i;:::-;40535:2;40530:3;40526:12;40519:19;;40178:366;;;:::o;40550:419::-;40716:4;40754:2;40743:9;40739:18;40731:26;;40803:9;40797:4;40793:20;40789:1;40778:9;40774:17;40767:47;40831:131;40957:4;40831:131;:::i;:::-;40823:139;;40550:419;;;:::o;40975:98::-;41026:6;41060:5;41054:12;41044:22;;40975:98;;;:::o;41079:168::-;41162:11;41196:6;41191:3;41184:19;41236:4;41231:3;41227:14;41212:29;;41079:168;;;;:::o;41253:373::-;41339:3;41367:38;41399:5;41367:38;:::i;:::-;41421:70;41484:6;41479:3;41421:70;:::i;:::-;41414:77;;41500:65;41558:6;41553:3;41546:4;41539:5;41535:16;41500:65;:::i;:::-;41590:29;41612:6;41590:29;:::i;:::-;41585:3;41581:39;41574:46;;41343:283;41253:373;;;;:::o;41632:640::-;41827:4;41865:3;41854:9;41850:19;41842:27;;41879:71;41947:1;41936:9;41932:17;41923:6;41879:71;:::i;:::-;41960:72;42028:2;42017:9;42013:18;42004:6;41960:72;:::i;:::-;42042;42110:2;42099:9;42095:18;42086:6;42042:72;:::i;:::-;42161:9;42155:4;42151:20;42146:2;42135:9;42131:18;42124:48;42189:76;42260:4;42251:6;42189:76;:::i;:::-;42181:84;;41632:640;;;;;;;:::o;42278:141::-;42334:5;42365:6;42359:13;42350:22;;42381:32;42407:5;42381:32;:::i;:::-;42278:141;;;;:::o;42425:349::-;42494:6;42543:2;42531:9;42522:7;42518:23;42514:32;42511:119;;;42549:79;;:::i;:::-;42511:119;42669:1;42694:63;42749:7;42740:6;42729:9;42725:22;42694:63;:::i;:::-;42684:73;;42640:127;42425:349;;;;:::o;42780:148::-;42882:11;42919:3;42904:18;;42780:148;;;;:::o;42934:390::-;43040:3;43068:39;43101:5;43068:39;:::i;:::-;43123:89;43205:6;43200:3;43123:89;:::i;:::-;43116:96;;43221:65;43279:6;43274:3;43267:4;43260:5;43256:16;43221:65;:::i;:::-;43311:6;43306:3;43302:16;43295:23;;43044:280;42934:390;;;;:::o;43330:435::-;43510:3;43532:95;43623:3;43614:6;43532:95;:::i;:::-;43525:102;;43644:95;43735:3;43726:6;43644:95;:::i;:::-;43637:102;;43756:3;43749:10;;43330:435;;;;;:::o

Swarm Source

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