ETH Price: $3,886.63 (-0.68%)

Contract

0x5BC8C4B713B600bBBc9bFb52d524CcF59447Cb16
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Approval For...202170912024-07-02 6:38:11165 days ago1719902291IN
KASOKU: KASOKU Token
0 ETH0.000206273.4175655
Set Approval For...201809572024-06-27 5:32:47170 days ago1719466367IN
KASOKU: KASOKU Token
0 ETH0.00031515.21343998
Set Approval For...201529732024-06-23 7:41:23174 days ago1719128483IN
KASOKU: KASOKU Token
0 ETH0.000165832.74754866
Set Approval For...192579972024-02-18 23:40:35300 days ago1708299635IN
KASOKU: KASOKU Token
0 ETH0.0007230618.76668948
Set Approval For...189079282023-12-31 20:46:11349 days ago1704055571IN
KASOKU: KASOKU Token
0 ETH0.0009134615.13429562
Set Approval For...189079112023-12-31 20:42:47349 days ago1704055367IN
KASOKU: KASOKU Token
0 ETH0.000900614.90355784
Set Approval For...182936332023-10-06 19:46:11435 days ago1696621571IN
KASOKU: KASOKU Token
0 ETH0.000276157.1830257
Set Approval For...181046192023-09-10 7:55:47461 days ago1694332547IN
KASOKU: KASOKU Token
0 ETH0.000380629.90042199
Set Approval For...177115302023-07-17 7:35:59516 days ago1689579359IN
KASOKU: KASOKU Token
0 ETH0.0005697614.82014931
Set Approval For...177115302023-07-17 7:35:59516 days ago1689579359IN
KASOKU: KASOKU Token
0 ETH0.0005701114.82014931
Set Approval For...177045562023-07-16 8:05:47517 days ago1689494747IN
KASOKU: KASOKU Token
0 ETH0.0010017816.57457048
Set Approval For...174931192023-06-16 14:54:11547 days ago1686927251IN
KASOKU: KASOKU Token
0 ETH0.001531625.37570021
Set Approval For...170579442023-04-16 7:19:47608 days ago1681629587IN
KASOKU: KASOKU Token
0 ETH0.0015220925.21815569
Set Approval For...170223532023-04-11 3:58:35613 days ago1681185515IN
KASOKU: KASOKU Token
0 ETH0.0008798221.74720465
Set Approval For...170223522023-04-11 3:58:23613 days ago1681185503IN
KASOKU: KASOKU Token
0 ETH0.0013727522.74387192
Set Approval For...169902782023-04-06 14:53:59618 days ago1680792839IN
KASOKU: KASOKU Token
0 ETH0.0017973729.74359817
Transfer From169718142023-04-03 23:43:47621 days ago1680565427IN
KASOKU: KASOKU Token
0 ETH0.0011682925.7101205
Transfer From169435652023-03-31 0:17:23625 days ago1680221843IN
KASOKU: KASOKU Token
0 ETH0.0007868428.62925132
Transfer From169435652023-03-31 0:17:23625 days ago1680221843IN
KASOKU: KASOKU Token
0 ETH0.0016527328.62925132
Set Approval For...169248212023-03-28 9:03:11627 days ago1679994191IN
KASOKU: KASOKU Token
0 ETH0.001379522.82860783
Set Approval For...169237162023-03-28 5:18:23627 days ago1679980703IN
KASOKU: KASOKU Token
0 ETH0.0011204618.56393384
Set Approval For...168469702023-03-17 10:34:35638 days ago1679049275IN
KASOKU: KASOKU Token
0 ETH0.0012278920.34394049
Set Approval For...167543302023-03-04 9:56:47651 days ago1677923807IN
KASOKU: KASOKU Token
0 ETH0.0018416430.5125861
Set Approval For...167401562023-03-02 10:01:23653 days ago1677751283IN
KASOKU: KASOKU Token
0 ETH0.0012797321.2028046
Set Approval For...167199432023-02-27 13:52:11656 days ago1677505931IN
KASOKU: KASOKU Token
0 ETH0.0013543522.43008419
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block
From
To
166773862023-02-21 14:10:59662 days ago1676988659
KASOKU: KASOKU Token
9.98 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
KASOKU

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 2023-02-20
*/

// File: 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: contracts/ERC721A_royalty.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 1;
    }

    /**
     * @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 == 0x2a55205a || // ERC 2981 rotyalty
            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 virtual 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: contracts/IOperatorFilterRegistry.sol


pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);
    function register(address registrant) external;
    function registerAndSubscribe(address registrant, address subscription) external;
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;
    function unregister(address addr) external;
    function updateOperator(address registrant, address operator, bool filtered) external;
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
    function subscribe(address registrant, address registrantToSubscribe) external;
    function unsubscribe(address registrant, bool copyExistingEntries) external;
    function subscriptionOf(address addr) external returns (address registrant);
    function subscribers(address registrant) external returns (address[] memory);
    function subscriberAt(address registrant, uint256 index) external returns (address);
    function copyEntriesOf(address registrant, address registrantToCopy) external;
    function isOperatorFiltered(address registrant, address operator) external returns (bool);
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
    function filteredOperators(address addr) external returns (address[] memory);
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
    function isRegistered(address addr) external returns (bool);
    function codeHashOf(address addr) external returns (bytes32);
}

// File: contracts/OperatorFilterer.sol


pragma solidity ^0.8.13;


/**
 * @title  OperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 */
abstract contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

    constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (subscribe) {
                OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    OPERATOR_FILTER_REGISTRY.register(address(this));
                }
            }
        }
    }

    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    function _checkFilterOperator(address operator) internal view virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

// File: contracts/DefaultOperatorFilterer.sol


pragma solidity ^0.8.13;


/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 */
abstract contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}

// File: @openzeppelin/contracts/utils/math/Math.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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


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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

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

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

// File: @openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

// File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;




/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 * OpenZeppelin's JavaScript library generates merkle trees that are safe
 * against this attack out of the box.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: @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/finance/PaymentSplitter.sol


// OpenZeppelin Contracts (last updated v4.8.0) (finance/PaymentSplitter.sol)

pragma solidity ^0.8.0;




/**
 * @title PaymentSplitter
 * @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware
 * that the Ether will be split in this way, since it is handled transparently by the contract.
 *
 * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each
 * account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim
 * an amount proportional to the percentage of total shares they were assigned. The distribution of shares is set at the
 * time of contract deployment and can't be updated thereafter.
 *
 * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
 * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
 * function.
 *
 * NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and
 * tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you
 * to run tests before sending real value to this contract.
 */
contract PaymentSplitter is Context {
    event PayeeAdded(address account, uint256 shares);
    event PaymentReleased(address to, uint256 amount);
    event ERC20PaymentReleased(IERC20 indexed token, address to, uint256 amount);
    event PaymentReceived(address from, uint256 amount);

    uint256 private _totalShares;
    uint256 private _totalReleased;

    mapping(address => uint256) private _shares;
    mapping(address => uint256) private _released;
    address[] private _payees;

    mapping(IERC20 => uint256) private _erc20TotalReleased;
    mapping(IERC20 => mapping(address => uint256)) private _erc20Released;

    /**
     * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
     * the matching position in the `shares` array.
     *
     * All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
     * duplicates in `payees`.
     */
    constructor(address[] memory payees, uint256[] memory shares_) payable {
        require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch");
        require(payees.length > 0, "PaymentSplitter: no payees");

        for (uint256 i = 0; i < payees.length; i++) {
            _addPayee(payees[i], shares_[i]);
        }
    }

    /**
     * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully
     * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the
     * reliability of the events, and not the actual splitting of Ether.
     *
     * To learn more about this see the Solidity documentation for
     * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback
     * functions].
     */
    receive() external payable virtual {
        emit PaymentReceived(_msgSender(), msg.value);
    }

    /**
     * @dev Getter for the total shares held by payees.
     */
    function totalShares() public view returns (uint256) {
        return _totalShares;
    }

    /**
     * @dev Getter for the total amount of Ether already released.
     */
    function totalReleased() public view returns (uint256) {
        return _totalReleased;
    }

    /**
     * @dev Getter for the total amount of `token` already released. `token` should be the address of an IERC20
     * contract.
     */
    function totalReleased(IERC20 token) public view returns (uint256) {
        return _erc20TotalReleased[token];
    }

    /**
     * @dev Getter for the amount of shares held by an account.
     */
    function shares(address account) public view returns (uint256) {
        return _shares[account];
    }

    /**
     * @dev Getter for the amount of Ether already released to a payee.
     */
    function released(address account) public view returns (uint256) {
        return _released[account];
    }

    /**
     * @dev Getter for the amount of `token` tokens already released to a payee. `token` should be the address of an
     * IERC20 contract.
     */
    function released(IERC20 token, address account) public view returns (uint256) {
        return _erc20Released[token][account];
    }

    /**
     * @dev Getter for the address of the payee number `index`.
     */
    function payee(uint256 index) public view returns (address) {
        return _payees[index];
    }

    /**
     * @dev Getter for the amount of payee's releasable Ether.
     */
    function releasable(address account) public view returns (uint256) {
        uint256 totalReceived = address(this).balance + totalReleased();
        return _pendingPayment(account, totalReceived, released(account));
    }

    /**
     * @dev Getter for the amount of payee's releasable `token` tokens. `token` should be the address of an
     * IERC20 contract.
     */
    function releasable(IERC20 token, address account) public view returns (uint256) {
        uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token);
        return _pendingPayment(account, totalReceived, released(token, account));
    }

    /**
     * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the
     * total shares and their previous withdrawals.
     */
    function release(address payable account) public virtual {
        require(_shares[account] > 0, "PaymentSplitter: account has no shares");

        uint256 payment = releasable(account);

        require(payment != 0, "PaymentSplitter: account is not due payment");

        // _totalReleased is the sum of all values in _released.
        // If "_totalReleased += payment" does not overflow, then "_released[account] += payment" cannot overflow.
        _totalReleased += payment;
        unchecked {
            _released[account] += payment;
        }

        Address.sendValue(account, payment);
        emit PaymentReleased(account, payment);
    }

    /**
     * @dev Triggers a transfer to `account` of the amount of `token` tokens they are owed, according to their
     * percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20
     * contract.
     */
    function release(IERC20 token, address account) public virtual {
        require(_shares[account] > 0, "PaymentSplitter: account has no shares");

        uint256 payment = releasable(token, account);

        require(payment != 0, "PaymentSplitter: account is not due payment");

        // _erc20TotalReleased[token] is the sum of all values in _erc20Released[token].
        // If "_erc20TotalReleased[token] += payment" does not overflow, then "_erc20Released[token][account] += payment"
        // cannot overflow.
        _erc20TotalReleased[token] += payment;
        unchecked {
            _erc20Released[token][account] += payment;
        }

        SafeERC20.safeTransfer(token, account, payment);
        emit ERC20PaymentReleased(token, account, payment);
    }

    /**
     * @dev internal logic for computing the pending payment of an `account` given the token historical balances and
     * already released amounts.
     */
    function _pendingPayment(
        address account,
        uint256 totalReceived,
        uint256 alreadyReleased
    ) private view returns (uint256) {
        return (totalReceived * _shares[account]) / _totalShares - alreadyReleased;
    }

    /**
     * @dev Add a new payee to the contract.
     * @param account The address of the payee to add.
     * @param shares_ The number of shares owned by the payee.
     */
    function _addPayee(address account, uint256 shares_) private {
        require(account != address(0), "PaymentSplitter: account is the zero address");
        require(shares_ > 0, "PaymentSplitter: shares are 0");
        require(_shares[account] == 0, "PaymentSplitter: account already has shares");

        _payees.push(account);
        _shares[account] = shares_;
        _totalShares = _totalShares + shares_;
        emit PayeeAdded(account, shares_);
    }
}

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

// File: contracts/KASOKU.sol


pragma solidity ^0.8.12;







contract KASOKU is Ownable, ERC721A, PaymentSplitter, DefaultOperatorFilterer {

    using Strings for uint;

    enum Step {
        Before,
        WhitelistSale,
        PublicSale,
        SoldOut
    }

    string public baseURI;

    Step public sellingStep;

    uint public  MAX_SUPPLY = 999;
    uint public  MAX_TOTAL_PUBLIC = 999;
    uint public  MAX_TOTAL_WL = 999;


    uint public MAX_PER_WALLET_PUBLIC = 999;
    uint public MAX_PER_WALLET_WL = 3;


    uint public wlSalePrice = 0.01 ether;
    uint public publicSalePrice = 0.013 ether;

    bytes32 public merkleRootWL;


    mapping(address => uint) public amountNFTsperWalletPUBLIC;
    mapping(address => uint) public amountNFTsperWalletWL;


    uint private teamLength;

    uint96 royaltyFeesInBips;
    address royaltyReceiver;

    constructor(uint96 _royaltyFeesInBips, address[] memory _team, uint[] memory _teamShares, bytes32 _merkleRootWL, string memory _baseURI) ERC721A("KASOKU", "KASOKU")
    PaymentSplitter(_team, _teamShares) {
        merkleRootWL = _merkleRootWL;
        baseURI = _baseURI;
        teamLength = _team.length;
        royaltyFeesInBips = _royaltyFeesInBips;
        royaltyReceiver = msg.sender;
    }

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

   function whitelistMint(address _account, uint _quantity, bytes32[] calldata _proof) external payable callerIsUser {
        uint price = wlSalePrice;
        require(sellingStep == Step.WhitelistSale, "Whitelist sale is not activated");
        require(isWhiteListed(msg.sender, _proof), "Not whitelisted");
        require(amountNFTsperWalletWL[msg.sender] + _quantity <= MAX_PER_WALLET_WL, "Max per wallet limit reached");
        require(totalSupply() + _quantity <= MAX_TOTAL_WL, "Max supply exceeded");
        require(totalSupply() + _quantity <= MAX_SUPPLY, "Max supply exceeded");
        require(msg.value >= price * _quantity, "Not enought funds");
        amountNFTsperWalletWL[msg.sender] += _quantity;
        _safeMint(_account, _quantity);
    }


    function publicSaleMint(address _account, uint _quantity) external payable callerIsUser {
        uint price = publicSalePrice;
        require(price != 0, "Price is 0");
        require(sellingStep == Step.PublicSale, "Public sale is not activated");
        require(totalSupply() + _quantity <= MAX_TOTAL_PUBLIC, "Max supply exceeded");
        require(totalSupply() + _quantity <= MAX_SUPPLY, "Max supply exceeded");
        require(amountNFTsperWalletPUBLIC[msg.sender] + _quantity <= MAX_PER_WALLET_PUBLIC, "Max per wallet limit reached");
        require(msg.value >= price * _quantity, "Not enought funds");
        amountNFTsperWalletPUBLIC[msg.sender] += _quantity;
        _safeMint(_account, _quantity);
    }

    function gift(address _to, uint _quantity) external onlyOwner {
        require(totalSupply() + _quantity <= MAX_SUPPLY, "Reached max Supply");
        _safeMint(_to, _quantity);
    }

    function lowerSupply (uint _MAX_SUPPLY) external onlyOwner{
        require(_MAX_SUPPLY < MAX_SUPPLY, "Cannot increase supply!");
        MAX_SUPPLY = _MAX_SUPPLY;
    }

    function setMaxTotalPUBLIC(uint _MAX_TOTAL_PUBLIC) external onlyOwner {
        MAX_TOTAL_PUBLIC = _MAX_TOTAL_PUBLIC;
    }

    function setMaxTotalWL(uint _MAX_TOTAL_WL) external onlyOwner {
        MAX_TOTAL_WL = _MAX_TOTAL_WL;
    }

    function setMaxPerWalletWL(uint _MAX_PER_WALLET_WL) external onlyOwner {
        MAX_PER_WALLET_WL = _MAX_PER_WALLET_WL;
    }

    function setMaxPerWalletPUBLIC(uint _MAX_PER_WALLET_PUBLIC) external onlyOwner {
        MAX_PER_WALLET_PUBLIC = _MAX_PER_WALLET_PUBLIC;
    }

    function setWLSalePrice(uint _wlSalePrice) external onlyOwner {
        wlSalePrice = _wlSalePrice;
    }

    function setPublicSalePrice(uint _publicSalePrice) external onlyOwner {
        publicSalePrice = _publicSalePrice;
    }

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

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

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

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

    //Whitelist
    function setMerkleRootWL(bytes32 _merkleRootWL) external onlyOwner {
        merkleRootWL = _merkleRootWL;
    }

    function isWhiteListed(address _account, bytes32[] calldata _proof) internal view returns(bool) {
        return _verifyWL(leaf(_account), _proof);
    }

    function leaf(address _account) internal pure returns(bytes32) {
        return keccak256(abi.encodePacked(_account));
    }

    function _verifyWL(bytes32 _leaf, bytes32[] memory _proof) internal view returns(bool) {
        return MerkleProof.verify(_proof, merkleRootWL, _leaf);
    }

    function royaltyInfo (
    uint256 _tokenId,
    uint256 _salePrice
     ) external view returns (
        address receiver,
        uint256 royaltyAmount
     ){
         return (royaltyReceiver, calculateRoyalty(_salePrice));
     }

    function calculateRoyalty(uint256 _salePrice) view public returns (uint256){
        return(_salePrice / 10000) * royaltyFeesInBips;
    }

    function setRoyaltyInfo (address _receiver, uint96 _royaltyFeesInBips) public onlyOwner {
        royaltyReceiver = _receiver;
        royaltyFeesInBips = _royaltyFeesInBips;
    }

    function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {
        super.setApprovalForAll(operator, approved);
    }

    function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) {
        super.approve(operator, tokenId);
    }

    function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId);
    }
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data)
        public
        override
        onlyAllowedOperator(from)
    {
        super.safeTransferFrom(from, to, tokenId, data);
    }

    //ReleaseALL
    function releaseAll() external onlyOwner {
        for(uint i = 0 ; i < teamLength ; i++) {
            release(payable(payee(i)));
        }
    }

    receive() override external payable {
        revert('Only if you mint');
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint96","name":"_royaltyFeesInBips","type":"uint96"},{"internalType":"address[]","name":"_team","type":"address[]"},{"internalType":"uint256[]","name":"_teamShares","type":"uint256[]"},{"internalType":"bytes32","name":"_merkleRootWL","type":"bytes32"},{"internalType":"string","name":"_baseURI","type":"string"}],"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":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","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":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"PayeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","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_PER_WALLET_PUBLIC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PER_WALLET_WL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOTAL_PUBLIC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOTAL_WL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"amountNFTsperWalletPUBLIC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"amountNFTsperWalletWL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"calculateRoyalty","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":"_to","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"gift","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_MAX_SUPPLY","type":"uint256"}],"name":"lowerSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"merkleRootWL","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"payee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"publicSaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"publicSalePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"releasable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"releasable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"releaseAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","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":"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":"sellingStep","outputs":[{"internalType":"enum KASOKU.Step","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_MAX_PER_WALLET_PUBLIC","type":"uint256"}],"name":"setMaxPerWalletPUBLIC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_MAX_PER_WALLET_WL","type":"uint256"}],"name":"setMaxPerWalletWL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_MAX_TOTAL_PUBLIC","type":"uint256"}],"name":"setMaxTotalPUBLIC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_MAX_TOTAL_WL","type":"uint256"}],"name":"setMaxTotalWL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRootWL","type":"bytes32"}],"name":"setMerkleRootWL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_publicSalePrice","type":"uint256"}],"name":"setPublicSalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint96","name":"_royaltyFeesInBips","type":"uint96"}],"name":"setRoyaltyInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_step","type":"uint256"}],"name":"setStep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_wlSalePrice","type":"uint256"}],"name":"setWLSalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"wlSalePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040526103e76012556103e76013556103e76014556103e76015556003601655662386f26fc10000601755662e2f6e5e1480006018553480156200004457600080fd5b5060405162006dcc38038062006dcc83398181016040528101906200006a919062000c56565b733cc6cdda760b79bafa08df41ecfa224f810dceb6600185856040518060400160405280600681526020017f4b41534f4b5500000000000000000000000000000000000000000000000000008152506040518060400160405280600681526020017f4b41534f4b5500000000000000000000000000000000000000000000000000008152506200010f62000103620004e060201b60201c565b620004e860201b60201c565b816003908162000120919062000f7c565b50806004908162000132919062000f7c565b5062000143620005ac60201b60201c565b6001819055505050805182511462000192576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200018990620010ea565b60405180910390fd5b6000825111620001d9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001d0906200115c565b60405180910390fd5b60005b82518110156200024857620002328382815181106200020057620001ff6200117e565b5b60200260200101518383815181106200021e576200021d6200117e565b5b6020026020010151620005b560201b60201c565b80806200023f90620011dc565b915050620001dc565b50505060006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156200044057801562000306576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b8152600401620002cc9291906200123a565b600060405180830381600087803b158015620002e757600080fd5b505af1158015620002fc573d6000803e3d6000fd5b505050506200043f565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620003c0576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b8152600401620003869291906200123a565b600060405180830381600087803b158015620003a157600080fd5b505af1158015620003b6573d6000803e3d6000fd5b505050506200043e565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b815260040162000409919062001267565b600060405180830381600087803b1580156200042457600080fd5b505af115801562000439573d6000803e3d6000fd5b505050505b5b5b50508160198190555080601090816200045a919062000f7c565b508351601c8190555084601d60006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555033601d600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050506200149f565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006001905090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000627576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200061e90620012fa565b60405180910390fd5b600081116200066d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000664906200136c565b60405180910390fd5b6000600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414620006f2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620006e99062001404565b60405180910390fd5b600d829080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080600954620007a9919062001426565b6009819055507f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac8282604051620007e292919062001472565b60405180910390a15050565b6000604051905090565b600080fd5b600080fd5b60006bffffffffffffffffffffffff82169050919050565b620008258162000802565b81146200083157600080fd5b50565b60008151905062000845816200081a565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200089b8262000850565b810181811067ffffffffffffffff82111715620008bd57620008bc62000861565b5b80604052505050565b6000620008d2620007ee565b9050620008e0828262000890565b919050565b600067ffffffffffffffff82111562000903576200090262000861565b5b602082029050602081019050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620009468262000919565b9050919050565b620009588162000939565b81146200096457600080fd5b50565b60008151905062000978816200094d565b92915050565b6000620009956200098f84620008e5565b620008c6565b90508083825260208201905060208402830185811115620009bb57620009ba62000914565b5b835b81811015620009e85780620009d3888262000967565b845260208401935050602081019050620009bd565b5050509392505050565b600082601f83011262000a0a5762000a096200084b565b5b815162000a1c8482602086016200097e565b91505092915050565b600067ffffffffffffffff82111562000a435762000a4262000861565b5b602082029050602081019050919050565b6000819050919050565b62000a698162000a54565b811462000a7557600080fd5b50565b60008151905062000a898162000a5e565b92915050565b600062000aa662000aa08462000a25565b620008c6565b9050808382526020820190506020840283018581111562000acc5762000acb62000914565b5b835b8181101562000af9578062000ae4888262000a78565b84526020840193505060208101905062000ace565b5050509392505050565b600082601f83011262000b1b5762000b1a6200084b565b5b815162000b2d84826020860162000a8f565b91505092915050565b6000819050919050565b62000b4b8162000b36565b811462000b5757600080fd5b50565b60008151905062000b6b8162000b40565b92915050565b600080fd5b600067ffffffffffffffff82111562000b945762000b9362000861565b5b62000b9f8262000850565b9050602081019050919050565b60005b8381101562000bcc57808201518184015260208101905062000baf565b60008484015250505050565b600062000bef62000be98462000b76565b620008c6565b90508281526020810184848401111562000c0e5762000c0d62000b71565b5b62000c1b84828562000bac565b509392505050565b600082601f83011262000c3b5762000c3a6200084b565b5b815162000c4d84826020860162000bd8565b91505092915050565b600080600080600060a0868803121562000c755762000c74620007f8565b5b600062000c858882890162000834565b955050602086015167ffffffffffffffff81111562000ca95762000ca8620007fd565b5b62000cb788828901620009f2565b945050604086015167ffffffffffffffff81111562000cdb5762000cda620007fd565b5b62000ce98882890162000b03565b935050606062000cfc8882890162000b5a565b925050608086015167ffffffffffffffff81111562000d205762000d1f620007fd565b5b62000d2e8882890162000c23565b9150509295509295909350565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168062000d8e57607f821691505b60208210810362000da45762000da362000d46565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830262000e0e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000dcf565b62000e1a868362000dcf565b95508019841693508086168417925050509392505050565b6000819050919050565b600062000e5d62000e5762000e518462000a54565b62000e32565b62000a54565b9050919050565b6000819050919050565b62000e798362000e3c565b62000e9162000e888262000e64565b84845462000ddc565b825550505050565b600090565b62000ea862000e99565b62000eb581848462000e6e565b505050565b5b8181101562000edd5762000ed160008262000e9e565b60018101905062000ebb565b5050565b601f82111562000f2c5762000ef68162000daa565b62000f018462000dbf565b8101602085101562000f11578190505b62000f2962000f208562000dbf565b83018262000eba565b50505b505050565b600082821c905092915050565b600062000f516000198460080262000f31565b1980831691505092915050565b600062000f6c838362000f3e565b9150826002028217905092915050565b62000f878262000d3b565b67ffffffffffffffff81111562000fa35762000fa262000861565b5b62000faf825462000d75565b62000fbc82828562000ee1565b600060209050601f83116001811462000ff4576000841562000fdf578287015190505b62000feb858262000f5e565b8655506200105b565b601f198416620010048662000daa565b60005b828110156200102e5784890151825560018201915060208501945060208101905062001007565b868310156200104e57848901516200104a601f89168262000f3e565b8355505b6001600288020188555050505b505050505050565b600082825260208201905092915050565b7f5061796d656e7453706c69747465723a2070617965657320616e64207368617260008201527f6573206c656e677468206d69736d617463680000000000000000000000000000602082015250565b6000620010d260328362001063565b9150620010df8262001074565b604082019050919050565b600060208201905081810360008301526200110581620010c3565b9050919050565b7f5061796d656e7453706c69747465723a206e6f20706179656573000000000000600082015250565b600062001144601a8362001063565b915062001151826200110c565b602082019050919050565b60006020820190508181036000830152620011778162001135565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000620011e98262000a54565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036200121e576200121d620011ad565b5b600182019050919050565b620012348162000939565b82525050565b600060408201905062001251600083018562001229565b62001260602083018462001229565b9392505050565b60006020820190506200127e600083018462001229565b92915050565b7f5061796d656e7453706c69747465723a206163636f756e74206973207468652060008201527f7a65726f20616464726573730000000000000000000000000000000000000000602082015250565b6000620012e2602c8362001063565b9150620012ef8262001284565b604082019050919050565b600060208201905081810360008301526200131581620012d3565b9050919050565b7f5061796d656e7453706c69747465723a20736861726573206172652030000000600082015250565b600062001354601d8362001063565b915062001361826200131c565b602082019050919050565b60006020820190508181036000830152620013878162001345565b9050919050565b7f5061796d656e7453706c69747465723a206163636f756e7420616c726561647960008201527f2068617320736861726573000000000000000000000000000000000000000000602082015250565b6000620013ec602b8362001063565b9150620013f9826200138e565b604082019050919050565b600060208201905081810360008301526200141f81620013dd565b9050919050565b6000620014338262000a54565b9150620014408362000a54565b92508282019050808211156200145b576200145a620011ad565b5b92915050565b6200146c8162000a54565b82525050565b600060408201905062001489600083018562001229565b62001498602083018462001461565b9392505050565b61591d80620014af6000396000f3fe6080604052600436106103855760003560e01c80638b83209b116101d1578063b74ce1f011610102578063cbce4c97116100a0578063e33b7de31161006f578063e33b7de314610d93578063e985e9c514610dbe578063f2fde38b14610dfb578063f8dcbddb14610e24576103c5565b8063cbce4c9714610cc5578063ce7c2ac214610cee578063d6492d8114610d2b578063d79779b214610d56576103c5565b8063c45ac050116100dc578063c45ac05014610bf7578063c715381614610c34578063c87b56dd14610c5d578063cbccefb214610c9a576103c5565b8063b74ce1f014610b7c578063b88d4fde14610ba5578063c1612d4114610bce576103c5565b8063a0bcfc7f1161016f578063a3f8eace11610149578063a3f8eace14610ad1578063aac0d2f614610b0e578063ac5ae11b14610b37578063ad3e31b714610b53576103c5565b8063a0bcfc7f14610a42578063a22cb46514610a6b578063a2e6961314610a94576103c5565b8063952aeab8116101ab578063952aeab81461097257806395d89b41146109af5780639852595c146109da5780639b6860c814610a17576103c5565b80638b83209b146108cd5780638da5cb5b1461090a5780638eb478a614610935576103c5565b8063406072a9116102b65780636352211e11610254578063715018a611610223578063715018a614610837578063734c66bd1461084e578063791a251914610879578063828122ab146108a2576103c5565b80636352211e1461076757806364affb40146107a45780636c0360eb146107cf57806370a08231146107fa576103c5565b806348b750441161029057806348b75044146106e25780634b11faaf1461070b57806355cf5912146107275780635be7fde814610750576103c5565b8063406072a91461065157806341f434341461068e57806342842e0e146106b9576103c5565b806317d5e67a1161032357806323b872dd116102fd57806323b872dd146105945780632a55205a146105bd57806332cb6b0c146105fb5780633a98ef3914610626576103c5565b806317d5e67a1461051557806318160ddd14610540578063191655871461056b576103c5565b8063080594391161035f578063080594391461045b578063081812fc1461048457806308ab701c146104c1578063095ea7b3146104ec576103c5565b806301ffc9a7146103ca57806302fa7c471461040757806306fdde0314610430576103c5565b366103c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103bc90613be7565b60405180910390fd5b600080fd5b3480156103d657600080fd5b506103f160048036038101906103ec9190613c73565b610e4d565b6040516103fe9190613cbb565b60405180910390f35b34801561041357600080fd5b5061042e60048036038101906104299190613d78565b610f0f565b005b34801561043c57600080fd5b50610445610f8d565b6040516104529190613e37565b60405180910390f35b34801561046757600080fd5b50610482600480360381019061047d9190613e8f565b61101f565b005b34801561049057600080fd5b506104ab60048036038101906104a69190613e8f565b611031565b6040516104b89190613ecb565b60405180910390f35b3480156104cd57600080fd5b506104d66110ad565b6040516104e39190613ef5565b60405180910390f35b3480156104f857600080fd5b50610513600480360381019061050e9190613f10565b6110b3565b005b34801561052157600080fd5b5061052a6110cc565b6040516105379190613ef5565b60405180910390f35b34801561054c57600080fd5b506105556110d2565b6040516105629190613ef5565b60405180910390f35b34801561057757600080fd5b50610592600480360381019061058d9190613f8e565b6110e9565b005b3480156105a057600080fd5b506105bb60048036038101906105b69190613fbb565b611268565b005b3480156105c957600080fd5b506105e460048036038101906105df919061400e565b6112b7565b6040516105f292919061404e565b60405180910390f35b34801561060757600080fd5b506106106112f1565b60405161061d9190613ef5565b60405180910390f35b34801561063257600080fd5b5061063b6112f7565b6040516106489190613ef5565b60405180910390f35b34801561065d57600080fd5b50610678600480360381019061067391906140b5565b611301565b6040516106859190613ef5565b60405180910390f35b34801561069a57600080fd5b506106a3611388565b6040516106b09190614154565b60405180910390f35b3480156106c557600080fd5b506106e060048036038101906106db9190613fbb565b61139a565b005b3480156106ee57600080fd5b50610709600480360381019061070491906140b5565b6113e9565b005b610725600480360381019061072091906141d4565b6115fc565b005b34801561073357600080fd5b5061074e60048036038101906107499190613e8f565b611923565b005b34801561075c57600080fd5b50610765611935565b005b34801561077357600080fd5b5061078e60048036038101906107899190613e8f565b611971565b60405161079b9190613ecb565b60405180910390f35b3480156107b057600080fd5b506107b9611983565b6040516107c69190613ef5565b60405180910390f35b3480156107db57600080fd5b506107e4611989565b6040516107f19190613e37565b60405180910390f35b34801561080657600080fd5b50610821600480360381019061081c9190614248565b611a17565b60405161082e9190613ef5565b60405180910390f35b34801561084357600080fd5b5061084c611acf565b005b34801561085a57600080fd5b50610863611ae3565b6040516108709190613ef5565b60405180910390f35b34801561088557600080fd5b506108a0600480360381019061089b9190613e8f565b611ae9565b005b3480156108ae57600080fd5b506108b7611afb565b6040516108c49190613ef5565b60405180910390f35b3480156108d957600080fd5b506108f460048036038101906108ef9190613e8f565b611b01565b6040516109019190613ecb565b60405180910390f35b34801561091657600080fd5b5061091f611b49565b60405161092c9190613ecb565b60405180910390f35b34801561094157600080fd5b5061095c60048036038101906109579190614248565b611b72565b6040516109699190613ef5565b60405180910390f35b34801561097e57600080fd5b5061099960048036038101906109949190614248565b611b8a565b6040516109a69190613ef5565b60405180910390f35b3480156109bb57600080fd5b506109c4611ba2565b6040516109d19190613e37565b60405180910390f35b3480156109e657600080fd5b50610a0160048036038101906109fc9190614248565b611c34565b604051610a0e9190613ef5565b60405180910390f35b348015610a2357600080fd5b50610a2c611c7d565b604051610a399190613ef5565b60405180910390f35b348015610a4e57600080fd5b50610a696004803603810190610a6491906143a5565b611c83565b005b348015610a7757600080fd5b50610a926004803603810190610a8d919061441a565b611c9e565b005b348015610aa057600080fd5b50610abb6004803603810190610ab69190613e8f565b611cb7565b604051610ac89190613ef5565b60405180910390f35b348015610add57600080fd5b50610af86004803603810190610af39190614248565b611d01565b604051610b059190613ef5565b60405180910390f35b348015610b1a57600080fd5b50610b356004803603810190610b309190613e8f565b611d34565b005b610b516004803603810190610b4c9190613f10565b611d46565b005b348015610b5f57600080fd5b50610b7a6004803603810190610b759190614490565b612064565b005b348015610b8857600080fd5b50610ba36004803603810190610b9e9190613e8f565b612076565b005b348015610bb157600080fd5b50610bcc6004803603810190610bc7919061455e565b612088565b005b348015610bda57600080fd5b50610bf56004803603810190610bf09190613e8f565b6120d9565b005b348015610c0357600080fd5b50610c1e6004803603810190610c1991906140b5565b6120eb565b604051610c2b9190613ef5565b60405180910390f35b348015610c4057600080fd5b50610c5b6004803603810190610c569190613e8f565b61219a565b005b348015610c6957600080fd5b50610c846004803603810190610c7f9190613e8f565b6121f0565b604051610c919190613e37565b60405180910390f35b348015610ca657600080fd5b50610caf61226c565b604051610cbc9190614658565b60405180910390f35b348015610cd157600080fd5b50610cec6004803603810190610ce79190613f10565b61227f565b005b348015610cfa57600080fd5b50610d156004803603810190610d109190614248565b6122ec565b604051610d229190613ef5565b60405180910390f35b348015610d3757600080fd5b50610d40612335565b604051610d4d9190614682565b60405180910390f35b348015610d6257600080fd5b50610d7d6004803603810190610d78919061469d565b61233b565b604051610d8a9190613ef5565b60405180910390f35b348015610d9f57600080fd5b50610da8612384565b604051610db59190613ef5565b60405180910390f35b348015610dca57600080fd5b50610de56004803603810190610de091906146ca565b61238e565b604051610df29190613cbb565b60405180910390f35b348015610e0757600080fd5b50610e226004803603810190610e1d9190614248565b612422565b005b348015610e3057600080fd5b50610e4b6004803603810190610e469190613e8f565b6124a5565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610ea857506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610ed85750632a55205a60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610f085750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b610f176124ec565b81601d600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080601d60006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050565b606060038054610f9c90614739565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc890614739565b80156110155780601f10610fea57610100808354040283529160200191611015565b820191906000526020600020905b815481529060010190602001808311610ff857829003601f168201915b5050505050905090565b6110276124ec565b8060178190555050565b600061103c8261256a565b611072576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60145481565b816110bd816125c9565b6110c783836126c6565b505050565b60135481565b60006110dc612807565b6002546001540303905090565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541161116b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611162906147dc565b60405180910390fd5b600061117682611d01565b9050600081036111bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111b29061486e565b60405180910390fd5b80600a60008282546111cd91906148bd565b9250508190555080600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061122b8282612810565b7fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056828260405161125c929190614912565b60405180910390a15050565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146112a6576112a5336125c9565b5b6112b1848484612904565b50505050565b600080601d600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166112e684611cb7565b915091509250929050565b60125481565b6000600954905090565b6000600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113d8576113d7336125c9565b5b6113e3848484612c26565b50505050565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541161146b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611462906147dc565b60405180910390fd5b600061147783836120eb565b9050600081036114bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114b39061486e565b60405180910390fd5b80600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461150b91906148bd565b9250508190555080600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506115a7838383612c46565b8273ffffffffffffffffffffffffffffffffffffffff167f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a83836040516115ef92919061404e565b60405180910390a2505050565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff161461166a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166190614987565b60405180910390fd5b6000601754905060016003811115611685576116846145e1565b5b601160009054906101000a900460ff1660038111156116a7576116a66145e1565b5b146116e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116de906149f3565b60405180910390fd5b6116f2338484612ccc565b611731576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172890614a5f565b60405180910390fd5b60165484601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461177f91906148bd565b11156117c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117b790614acb565b60405180910390fd5b601454846117cc6110d2565b6117d691906148bd565b1115611817576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180e90614b37565b60405180910390fd5b601254846118236110d2565b61182d91906148bd565b111561186e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186590614b37565b60405180910390fd5b838161187a9190614b57565b3410156118bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b390614be5565b60405180910390fd5b83601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461190b91906148bd565b9250508190555061191c8585612d2a565b5050505050565b61192b6124ec565b8060158190555050565b61193d6124ec565b60005b601c5481101561196e5761195b61195682611b01565b6110e9565b808061196690614c05565b915050611940565b50565b600061197c82612d48565b9050919050565b60155481565b6010805461199690614739565b80601f01602080910402602001604051908101604052809291908181526020018280546119c290614739565b8015611a0f5780601f106119e457610100808354040283529160200191611a0f565b820191906000526020600020905b8154815290600101906020018083116119f257829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611a7e576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611ad76124ec565b611ae16000612e14565b565b60175481565b611af16124ec565b8060188190555050565b60165481565b6000600d8281548110611b1757611b16614c4d565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601a6020528060005260406000206000915090505481565b601b6020528060005260406000206000915090505481565b606060048054611bb190614739565b80601f0160208091040260200160405190810160405280929190818152602001828054611bdd90614739565b8015611c2a5780601f10611bff57610100808354040283529160200191611c2a565b820191906000526020600020905b815481529060010190602001808311611c0d57829003601f168201915b5050505050905090565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60185481565b611c8b6124ec565b8060109081611c9a9190614e1e565b5050565b81611ca8816125c9565b611cb28383612ed8565b505050565b6000601d60009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff1661271083611cf09190614f1f565b611cfa9190614b57565b9050919050565b600080611d0c612384565b47611d1791906148bd565b9050611d2c8382611d2786611c34565b61304f565b915050919050565b611d3c6124ec565b8060148190555050565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614611db4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dab90614987565b60405180910390fd5b6000601854905060008103611dfe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611df590614f9c565b60405180910390fd5b60026003811115611e1257611e116145e1565b5b601160009054906101000a900460ff166003811115611e3457611e336145e1565b5b14611e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e6b90615008565b60405180910390fd5b60135482611e806110d2565b611e8a91906148bd565b1115611ecb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec290614b37565b60405180910390fd5b60125482611ed76110d2565b611ee191906148bd565b1115611f22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1990614b37565b60405180910390fd5b60155482601a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611f7091906148bd565b1115611fb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa890614acb565b60405180910390fd5b8181611fbd9190614b57565b341015611fff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ff690614be5565b60405180910390fd5b81601a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461204e91906148bd565b9250508190555061205f8383612d2a565b505050565b61206c6124ec565b8060198190555050565b61207e6124ec565b8060138190555050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146120c6576120c5336125c9565b5b6120d2858585856130bd565b5050505050565b6120e16124ec565b8060168190555050565b6000806120f78461233b565b8473ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016121309190613ecb565b602060405180830381865afa15801561214d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612171919061503d565b61217b91906148bd565b9050612191838261218c8787611301565b61304f565b91505092915050565b6121a26124ec565b60125481106121e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121dd906150b6565b60405180910390fd5b8060128190555050565b60606121fb8261256a565b61223a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223190615122565b60405180910390fd5b601061224583613130565b60405160200161225692919061524d565b6040516020818303038152906040529050919050565b601160009054906101000a900460ff1681565b6122876124ec565b601254816122936110d2565b61229d91906148bd565b11156122de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d5906152c8565b60405180910390fd5b6122e88282612d2a565b5050565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60195481565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000600a54905090565b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61242a6124ec565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612499576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124909061535a565b60405180910390fd5b6124a281612e14565b50565b6124ad6124ec565b8060038111156124c0576124bf6145e1565b5b601160006101000a81548160ff021916908360038111156124e4576124e36145e1565b5b021790555050565b6124f46131fe565b73ffffffffffffffffffffffffffffffffffffffff16612512611b49565b73ffffffffffffffffffffffffffffffffffffffff1614612568576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161255f906153c6565b60405180910390fd5b565b600081612575612807565b11158015612584575060015482105b80156125c2575060007c0100000000000000000000000000000000000000000000000000000000600560008581526020019081526020016000205416145b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156126c3576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016126409291906153e6565b602060405180830381865afa15801561265d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126819190615424565b6126c257806040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016126b99190613ecb565b60405180910390fd5b5b50565b60006126d182611971565b90508073ffffffffffffffffffffffffffffffffffffffff166126f2613206565b73ffffffffffffffffffffffffffffffffffffffff16146127555761271e81612719613206565b61238e565b612754576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826007600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b80471015612853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161284a9061549d565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff1682604051612879906154ee565b60006040518083038185875af1925050503d80600081146128b6576040519150601f19603f3d011682016040523d82523d6000602084013e6128bb565b606091505b50509050806128ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128f690615575565b60405180910390fd5b505050565b600061290f82612d48565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612976576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806129828461320e565b915091506129988187612993613206565b613230565b6129e4576129ad866129a8613206565b61238e565b6129e3576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612a4a576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a578686866001613274565b8015612a6257600082555b600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550612b3085612b0c88888761327a565b7c0200000000000000000000000000000000000000000000000000000000176132a2565b600560008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603612bb65760006001850190506000600560008381526020019081526020016000205403612bb4576001548114612bb3578360056000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612c1e86868660016132cd565b505050505050565b612c4183838360405180602001604052806000815250612088565b505050565b612cc78363a9059cbb60e01b8484604051602401612c6592919061404e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506132d3565b505050565b6000612d21612cda8561339a565b848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050506133ca565b90509392505050565b612d448282604051806020016040528060008152506133e1565b5050565b60008082905080612d57612807565b11612ddd57600154811015612ddc5760006005600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603612dda575b60008103612dd0576005600083600190039350838152602001908152602001600020549050612da6565b8092505050612e0f565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b612ee0613206565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612f44576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060086000612f51613206565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612ffe613206565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516130439190613cbb565b60405180910390a35050565b600081600954600b60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054856130a09190614b57565b6130aa9190614f1f565b6130b49190615595565b90509392505050565b6130c8848484611268565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461312a576130f38484848461347f565b613129576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60606000600161313f846135cf565b01905060008167ffffffffffffffff81111561315e5761315d61427a565b5b6040519080825280601f01601f1916602001820160405280156131905781602001600182028036833780820191505090505b509050600082602001820190505b6001156131f3578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816131e7576131e6614ef0565b5b0494506000850361319e575b819350505050919050565b600033905090565b600033905090565b6000806000600790508360005280602052604060002092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8613291868684613722565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000613335826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661372b9092919063ffffffff16565b905060008151111561339557808060200190518101906133559190615424565b613394576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161338b9061563b565b60405180910390fd5b5b505050565b6000816040516020016133ad91906156a3565b604051602081830303815290604052805190602001209050919050565b60006133d98260195485613743565b905092915050565b6133eb838361375a565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461347a5760006001549050600083820390505b61342c600086838060010194508661347f565b613462576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81811061341957816001541461347757600080fd5b50505b505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026134a5613206565b8786866040518563ffffffff1660e01b81526004016134c79493929190615713565b6020604051808303816000875af192505050801561350357506040513d601f19601f820116820180604052508101906135009190615774565b60015b61357c573d8060008114613533576040519150601f19603f3d011682016040523d82523d6000602084013e613538565b606091505b506000815103613574576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061362d577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161362357613622614ef0565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061366a576d04ee2d6d415b85acef810000000083816136605761365f614ef0565b5b0492506020810190505b662386f26fc10000831061369957662386f26fc10000838161368f5761368e614ef0565b5b0492506010810190505b6305f5e10083106136c2576305f5e10083816136b8576136b7614ef0565b5b0492506008810190505b61271083106136e75761271083816136dd576136dc614ef0565b5b0492506004810190505b6064831061370a5760648381613700576136ff614ef0565b5b0492506002810190505b600a8310613719576001810190505b80915050919050565b60009392505050565b606061373a848460008561392d565b90509392505050565b60008261375085846139fa565b1490509392505050565b60006001549050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036137c7576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008203613801576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61380e6000848385613274565b600160406001901b178202600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061388583613876600086600061327a565b61387f85613a50565b176132a2565b60056000838152602001908152602001600020819055506000819050600083830190505b818060010192508573ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082106138a95780600181905550505061392860008483856132cd565b505050565b606082471015613972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161396990615813565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161399b9190615864565b60006040518083038185875af1925050503d80600081146139d8576040519150601f19603f3d011682016040523d82523d6000602084013e6139dd565b606091505b50915091506139ee87838387613a60565b92505050949350505050565b60008082905060005b8451811015613a4557613a3082868381518110613a2357613a22614c4d565b5b6020026020010151613ad5565b91508080613a3d90614c05565b915050613a03565b508091505092915050565b60006001821460e11b9050919050565b60608315613ac2576000835103613aba57613a7a85613b00565b613ab9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613ab0906158c7565b60405180910390fd5b5b829050613acd565b613acc8383613b23565b5b949350505050565b6000818310613aed57613ae88284613b73565b613af8565b613af78383613b73565b5b905092915050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600082511115613b365781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613b6a9190613e37565b60405180910390fd5b600082600052816020526040600020905092915050565b600082825260208201905092915050565b7f4f6e6c7920696620796f75206d696e7400000000000000000000000000000000600082015250565b6000613bd1601083613b8a565b9150613bdc82613b9b565b602082019050919050565b60006020820190508181036000830152613c0081613bc4565b9050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613c5081613c1b565b8114613c5b57600080fd5b50565b600081359050613c6d81613c47565b92915050565b600060208284031215613c8957613c88613c11565b5b6000613c9784828501613c5e565b91505092915050565b60008115159050919050565b613cb581613ca0565b82525050565b6000602082019050613cd06000830184613cac565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613d0182613cd6565b9050919050565b613d1181613cf6565b8114613d1c57600080fd5b50565b600081359050613d2e81613d08565b92915050565b60006bffffffffffffffffffffffff82169050919050565b613d5581613d34565b8114613d6057600080fd5b50565b600081359050613d7281613d4c565b92915050565b60008060408385031215613d8f57613d8e613c11565b5b6000613d9d85828601613d1f565b9250506020613dae85828601613d63565b9150509250929050565b600081519050919050565b60005b83811015613de1578082015181840152602081019050613dc6565b60008484015250505050565b6000601f19601f8301169050919050565b6000613e0982613db8565b613e138185613b8a565b9350613e23818560208601613dc3565b613e2c81613ded565b840191505092915050565b60006020820190508181036000830152613e518184613dfe565b905092915050565b6000819050919050565b613e6c81613e59565b8114613e7757600080fd5b50565b600081359050613e8981613e63565b92915050565b600060208284031215613ea557613ea4613c11565b5b6000613eb384828501613e7a565b91505092915050565b613ec581613cf6565b82525050565b6000602082019050613ee06000830184613ebc565b92915050565b613eef81613e59565b82525050565b6000602082019050613f0a6000830184613ee6565b92915050565b60008060408385031215613f2757613f26613c11565b5b6000613f3585828601613d1f565b9250506020613f4685828601613e7a565b9150509250929050565b6000613f5b82613cd6565b9050919050565b613f6b81613f50565b8114613f7657600080fd5b50565b600081359050613f8881613f62565b92915050565b600060208284031215613fa457613fa3613c11565b5b6000613fb284828501613f79565b91505092915050565b600080600060608486031215613fd457613fd3613c11565b5b6000613fe286828701613d1f565b9350506020613ff386828701613d1f565b925050604061400486828701613e7a565b9150509250925092565b6000806040838503121561402557614024613c11565b5b600061403385828601613e7a565b925050602061404485828601613e7a565b9150509250929050565b60006040820190506140636000830185613ebc565b6140706020830184613ee6565b9392505050565b600061408282613cf6565b9050919050565b61409281614077565b811461409d57600080fd5b50565b6000813590506140af81614089565b92915050565b600080604083850312156140cc576140cb613c11565b5b60006140da858286016140a0565b92505060206140eb85828601613d1f565b9150509250929050565b6000819050919050565b600061411a61411561411084613cd6565b6140f5565b613cd6565b9050919050565b600061412c826140ff565b9050919050565b600061413e82614121565b9050919050565b61414e81614133565b82525050565b60006020820190506141696000830184614145565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126141945761419361416f565b5b8235905067ffffffffffffffff8111156141b1576141b0614174565b5b6020830191508360208202830111156141cd576141cc614179565b5b9250929050565b600080600080606085870312156141ee576141ed613c11565b5b60006141fc87828801613d1f565b945050602061420d87828801613e7a565b935050604085013567ffffffffffffffff81111561422e5761422d613c16565b5b61423a8782880161417e565b925092505092959194509250565b60006020828403121561425e5761425d613c11565b5b600061426c84828501613d1f565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6142b282613ded565b810181811067ffffffffffffffff821117156142d1576142d061427a565b5b80604052505050565b60006142e4613c07565b90506142f082826142a9565b919050565b600067ffffffffffffffff8211156143105761430f61427a565b5b61431982613ded565b9050602081019050919050565b82818337600083830152505050565b6000614348614343846142f5565b6142da565b90508281526020810184848401111561436457614363614275565b5b61436f848285614326565b509392505050565b600082601f83011261438c5761438b61416f565b5b813561439c848260208601614335565b91505092915050565b6000602082840312156143bb576143ba613c11565b5b600082013567ffffffffffffffff8111156143d9576143d8613c16565b5b6143e584828501614377565b91505092915050565b6143f781613ca0565b811461440257600080fd5b50565b600081359050614414816143ee565b92915050565b6000806040838503121561443157614430613c11565b5b600061443f85828601613d1f565b925050602061445085828601614405565b9150509250929050565b6000819050919050565b61446d8161445a565b811461447857600080fd5b50565b60008135905061448a81614464565b92915050565b6000602082840312156144a6576144a5613c11565b5b60006144b48482850161447b565b91505092915050565b600067ffffffffffffffff8211156144d8576144d761427a565b5b6144e182613ded565b9050602081019050919050565b60006145016144fc846144bd565b6142da565b90508281526020810184848401111561451d5761451c614275565b5b614528848285614326565b509392505050565b600082601f8301126145455761454461416f565b5b81356145558482602086016144ee565b91505092915050565b6000806000806080858703121561457857614577613c11565b5b600061458687828801613d1f565b945050602061459787828801613d1f565b93505060406145a887828801613e7a565b925050606085013567ffffffffffffffff8111156145c9576145c8613c16565b5b6145d587828801614530565b91505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110614621576146206145e1565b5b50565b600081905061463282614610565b919050565b600061464282614624565b9050919050565b61465281614637565b82525050565b600060208201905061466d6000830184614649565b92915050565b61467c8161445a565b82525050565b60006020820190506146976000830184614673565b92915050565b6000602082840312156146b3576146b2613c11565b5b60006146c1848285016140a0565b91505092915050565b600080604083850312156146e1576146e0613c11565b5b60006146ef85828601613d1f565b925050602061470085828601613d1f565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061475157607f821691505b6020821081036147645761476361470a565b5b50919050565b7f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060008201527f7368617265730000000000000000000000000000000000000000000000000000602082015250565b60006147c6602683613b8a565b91506147d18261476a565b604082019050919050565b600060208201905081810360008301526147f5816147b9565b9050919050565b7f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060008201527f647565207061796d656e74000000000000000000000000000000000000000000602082015250565b6000614858602b83613b8a565b9150614863826147fc565b604082019050919050565b600060208201905081810360008301526148878161484b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006148c882613e59565b91506148d383613e59565b92508282019050808211156148eb576148ea61488e565b5b92915050565b60006148fc82614121565b9050919050565b61490c816148f1565b82525050565b60006040820190506149276000830185614903565b6149346020830184613ee6565b9392505050565b7f5468652063616c6c657220697320616e6f7468657220636f6e74726163740000600082015250565b6000614971601e83613b8a565b915061497c8261493b565b602082019050919050565b600060208201905081810360008301526149a081614964565b9050919050565b7f57686974656c6973742073616c65206973206e6f742061637469766174656400600082015250565b60006149dd601f83613b8a565b91506149e8826149a7565b602082019050919050565b60006020820190508181036000830152614a0c816149d0565b9050919050565b7f4e6f742077686974656c69737465640000000000000000000000000000000000600082015250565b6000614a49600f83613b8a565b9150614a5482614a13565b602082019050919050565b60006020820190508181036000830152614a7881614a3c565b9050919050565b7f4d6178207065722077616c6c6574206c696d6974207265616368656400000000600082015250565b6000614ab5601c83613b8a565b9150614ac082614a7f565b602082019050919050565b60006020820190508181036000830152614ae481614aa8565b9050919050565b7f4d617820737570706c7920657863656564656400000000000000000000000000600082015250565b6000614b21601383613b8a565b9150614b2c82614aeb565b602082019050919050565b60006020820190508181036000830152614b5081614b14565b9050919050565b6000614b6282613e59565b9150614b6d83613e59565b9250828202614b7b81613e59565b91508282048414831517614b9257614b9161488e565b5b5092915050565b7f4e6f7420656e6f756768742066756e6473000000000000000000000000000000600082015250565b6000614bcf601183613b8a565b9150614bda82614b99565b602082019050919050565b60006020820190508181036000830152614bfe81614bc2565b9050919050565b6000614c1082613e59565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614c4257614c4161488e565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302614cde7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614ca1565b614ce88683614ca1565b95508019841693508086168417925050509392505050565b6000614d1b614d16614d1184613e59565b6140f5565b613e59565b9050919050565b6000819050919050565b614d3583614d00565b614d49614d4182614d22565b848454614cae565b825550505050565b600090565b614d5e614d51565b614d69818484614d2c565b505050565b5b81811015614d8d57614d82600082614d56565b600181019050614d6f565b5050565b601f821115614dd257614da381614c7c565b614dac84614c91565b81016020851015614dbb578190505b614dcf614dc785614c91565b830182614d6e565b50505b505050565b600082821c905092915050565b6000614df560001984600802614dd7565b1980831691505092915050565b6000614e0e8383614de4565b9150826002028217905092915050565b614e2782613db8565b67ffffffffffffffff811115614e4057614e3f61427a565b5b614e4a8254614739565b614e55828285614d91565b600060209050601f831160018114614e885760008415614e76578287015190505b614e808582614e02565b865550614ee8565b601f198416614e9686614c7c565b60005b82811015614ebe57848901518255600182019150602085019450602081019050614e99565b86831015614edb5784890151614ed7601f891682614de4565b8355505b6001600288020188555050505b505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614f2a82613e59565b9150614f3583613e59565b925082614f4557614f44614ef0565b5b828204905092915050565b7f5072696365206973203000000000000000000000000000000000000000000000600082015250565b6000614f86600a83613b8a565b9150614f9182614f50565b602082019050919050565b60006020820190508181036000830152614fb581614f79565b9050919050565b7f5075626c69632073616c65206973206e6f742061637469766174656400000000600082015250565b6000614ff2601c83613b8a565b9150614ffd82614fbc565b602082019050919050565b6000602082019050818103600083015261502181614fe5565b9050919050565b60008151905061503781613e63565b92915050565b60006020828403121561505357615052613c11565b5b600061506184828501615028565b91505092915050565b7f43616e6e6f7420696e63726561736520737570706c7921000000000000000000600082015250565b60006150a0601783613b8a565b91506150ab8261506a565b602082019050919050565b600060208201905081810360008301526150cf81615093565b9050919050565b7f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e00600082015250565b600061510c601f83613b8a565b9150615117826150d6565b602082019050919050565b6000602082019050818103600083015261513b816150ff565b9050919050565b600081905092915050565b6000815461515a81614739565b6151648186615142565b9450600182166000811461517f5760018114615194576151c7565b60ff19831686528115158202860193506151c7565b61519d85614c7c565b60005b838110156151bf578154818901526001820191506020810190506151a0565b838801955050505b50505092915050565b60006151db82613db8565b6151e58185615142565b93506151f5818560208601613dc3565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000615237600583615142565b915061524282615201565b600582019050919050565b6000615259828561514d565b915061526582846151d0565b91506152708261522a565b91508190509392505050565b7f52656163686564206d617820537570706c790000000000000000000000000000600082015250565b60006152b2601283613b8a565b91506152bd8261527c565b602082019050919050565b600060208201905081810360008301526152e1816152a5565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615344602683613b8a565b915061534f826152e8565b604082019050919050565b6000602082019050818103600083015261537381615337565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006153b0602083613b8a565b91506153bb8261537a565b602082019050919050565b600060208201905081810360008301526153df816153a3565b9050919050565b60006040820190506153fb6000830185613ebc565b6154086020830184613ebc565b9392505050565b60008151905061541e816143ee565b92915050565b60006020828403121561543a57615439613c11565b5b60006154488482850161540f565b91505092915050565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b6000615487601d83613b8a565b915061549282615451565b602082019050919050565b600060208201905081810360008301526154b68161547a565b9050919050565b600081905092915050565b50565b60006154d86000836154bd565b91506154e3826154c8565b600082019050919050565b60006154f9826154cb565b9150819050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b600061555f603a83613b8a565b915061556a82615503565b604082019050919050565b6000602082019050818103600083015261558e81615552565b9050919050565b60006155a082613e59565b91506155ab83613e59565b92508282039050818111156155c3576155c261488e565b5b92915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000615625602a83613b8a565b9150615630826155c9565b604082019050919050565b6000602082019050818103600083015261565481615618565b9050919050565b60008160601b9050919050565b60006156738261565b565b9050919050565b600061568582615668565b9050919050565b61569d61569882613cf6565b61567a565b82525050565b60006156af828461568c565b60148201915081905092915050565b600081519050919050565b600082825260208201905092915050565b60006156e5826156be565b6156ef81856156c9565b93506156ff818560208601613dc3565b61570881613ded565b840191505092915050565b60006080820190506157286000830187613ebc565b6157356020830186613ebc565b6157426040830185613ee6565b818103606083015261575481846156da565b905095945050505050565b60008151905061576e81613c47565b92915050565b60006020828403121561578a57615789613c11565b5b60006157988482850161575f565b91505092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006157fd602683613b8a565b9150615808826157a1565b604082019050919050565b6000602082019050818103600083015261582c816157f0565b9050919050565b600061583e826156be565b61584881856154bd565b9350615858818560208601613dc3565b80840191505092915050565b60006158708284615833565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006158b1601d83613b8a565b91506158bc8261587b565b602082019050919050565b600060208201905081810360008301526158e0816158a4565b905091905056fea2646970667358221220407d7ffd3c55490253a534f3b92cb9204f804d64bd474ea7b48161e4c0fcd09164736f6c6343000811003300000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e068a09eb3cb3252fa5655f26180ac67bd2972a02533771890d77b679aecfd481300000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000b3eb7ada0ea10f007e0380d26e65e26e598539b6000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000043697066733a2f2f6261667962656965776e79783237377777696f33706e3632716e67617273776d346e65646a6e6370613273637777616b346f656b61723674776b712f0000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106103855760003560e01c80638b83209b116101d1578063b74ce1f011610102578063cbce4c97116100a0578063e33b7de31161006f578063e33b7de314610d93578063e985e9c514610dbe578063f2fde38b14610dfb578063f8dcbddb14610e24576103c5565b8063cbce4c9714610cc5578063ce7c2ac214610cee578063d6492d8114610d2b578063d79779b214610d56576103c5565b8063c45ac050116100dc578063c45ac05014610bf7578063c715381614610c34578063c87b56dd14610c5d578063cbccefb214610c9a576103c5565b8063b74ce1f014610b7c578063b88d4fde14610ba5578063c1612d4114610bce576103c5565b8063a0bcfc7f1161016f578063a3f8eace11610149578063a3f8eace14610ad1578063aac0d2f614610b0e578063ac5ae11b14610b37578063ad3e31b714610b53576103c5565b8063a0bcfc7f14610a42578063a22cb46514610a6b578063a2e6961314610a94576103c5565b8063952aeab8116101ab578063952aeab81461097257806395d89b41146109af5780639852595c146109da5780639b6860c814610a17576103c5565b80638b83209b146108cd5780638da5cb5b1461090a5780638eb478a614610935576103c5565b8063406072a9116102b65780636352211e11610254578063715018a611610223578063715018a614610837578063734c66bd1461084e578063791a251914610879578063828122ab146108a2576103c5565b80636352211e1461076757806364affb40146107a45780636c0360eb146107cf57806370a08231146107fa576103c5565b806348b750441161029057806348b75044146106e25780634b11faaf1461070b57806355cf5912146107275780635be7fde814610750576103c5565b8063406072a91461065157806341f434341461068e57806342842e0e146106b9576103c5565b806317d5e67a1161032357806323b872dd116102fd57806323b872dd146105945780632a55205a146105bd57806332cb6b0c146105fb5780633a98ef3914610626576103c5565b806317d5e67a1461051557806318160ddd14610540578063191655871461056b576103c5565b8063080594391161035f578063080594391461045b578063081812fc1461048457806308ab701c146104c1578063095ea7b3146104ec576103c5565b806301ffc9a7146103ca57806302fa7c471461040757806306fdde0314610430576103c5565b366103c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103bc90613be7565b60405180910390fd5b600080fd5b3480156103d657600080fd5b506103f160048036038101906103ec9190613c73565b610e4d565b6040516103fe9190613cbb565b60405180910390f35b34801561041357600080fd5b5061042e60048036038101906104299190613d78565b610f0f565b005b34801561043c57600080fd5b50610445610f8d565b6040516104529190613e37565b60405180910390f35b34801561046757600080fd5b50610482600480360381019061047d9190613e8f565b61101f565b005b34801561049057600080fd5b506104ab60048036038101906104a69190613e8f565b611031565b6040516104b89190613ecb565b60405180910390f35b3480156104cd57600080fd5b506104d66110ad565b6040516104e39190613ef5565b60405180910390f35b3480156104f857600080fd5b50610513600480360381019061050e9190613f10565b6110b3565b005b34801561052157600080fd5b5061052a6110cc565b6040516105379190613ef5565b60405180910390f35b34801561054c57600080fd5b506105556110d2565b6040516105629190613ef5565b60405180910390f35b34801561057757600080fd5b50610592600480360381019061058d9190613f8e565b6110e9565b005b3480156105a057600080fd5b506105bb60048036038101906105b69190613fbb565b611268565b005b3480156105c957600080fd5b506105e460048036038101906105df919061400e565b6112b7565b6040516105f292919061404e565b60405180910390f35b34801561060757600080fd5b506106106112f1565b60405161061d9190613ef5565b60405180910390f35b34801561063257600080fd5b5061063b6112f7565b6040516106489190613ef5565b60405180910390f35b34801561065d57600080fd5b50610678600480360381019061067391906140b5565b611301565b6040516106859190613ef5565b60405180910390f35b34801561069a57600080fd5b506106a3611388565b6040516106b09190614154565b60405180910390f35b3480156106c557600080fd5b506106e060048036038101906106db9190613fbb565b61139a565b005b3480156106ee57600080fd5b50610709600480360381019061070491906140b5565b6113e9565b005b610725600480360381019061072091906141d4565b6115fc565b005b34801561073357600080fd5b5061074e60048036038101906107499190613e8f565b611923565b005b34801561075c57600080fd5b50610765611935565b005b34801561077357600080fd5b5061078e60048036038101906107899190613e8f565b611971565b60405161079b9190613ecb565b60405180910390f35b3480156107b057600080fd5b506107b9611983565b6040516107c69190613ef5565b60405180910390f35b3480156107db57600080fd5b506107e4611989565b6040516107f19190613e37565b60405180910390f35b34801561080657600080fd5b50610821600480360381019061081c9190614248565b611a17565b60405161082e9190613ef5565b60405180910390f35b34801561084357600080fd5b5061084c611acf565b005b34801561085a57600080fd5b50610863611ae3565b6040516108709190613ef5565b60405180910390f35b34801561088557600080fd5b506108a0600480360381019061089b9190613e8f565b611ae9565b005b3480156108ae57600080fd5b506108b7611afb565b6040516108c49190613ef5565b60405180910390f35b3480156108d957600080fd5b506108f460048036038101906108ef9190613e8f565b611b01565b6040516109019190613ecb565b60405180910390f35b34801561091657600080fd5b5061091f611b49565b60405161092c9190613ecb565b60405180910390f35b34801561094157600080fd5b5061095c60048036038101906109579190614248565b611b72565b6040516109699190613ef5565b60405180910390f35b34801561097e57600080fd5b5061099960048036038101906109949190614248565b611b8a565b6040516109a69190613ef5565b60405180910390f35b3480156109bb57600080fd5b506109c4611ba2565b6040516109d19190613e37565b60405180910390f35b3480156109e657600080fd5b50610a0160048036038101906109fc9190614248565b611c34565b604051610a0e9190613ef5565b60405180910390f35b348015610a2357600080fd5b50610a2c611c7d565b604051610a399190613ef5565b60405180910390f35b348015610a4e57600080fd5b50610a696004803603810190610a6491906143a5565b611c83565b005b348015610a7757600080fd5b50610a926004803603810190610a8d919061441a565b611c9e565b005b348015610aa057600080fd5b50610abb6004803603810190610ab69190613e8f565b611cb7565b604051610ac89190613ef5565b60405180910390f35b348015610add57600080fd5b50610af86004803603810190610af39190614248565b611d01565b604051610b059190613ef5565b60405180910390f35b348015610b1a57600080fd5b50610b356004803603810190610b309190613e8f565b611d34565b005b610b516004803603810190610b4c9190613f10565b611d46565b005b348015610b5f57600080fd5b50610b7a6004803603810190610b759190614490565b612064565b005b348015610b8857600080fd5b50610ba36004803603810190610b9e9190613e8f565b612076565b005b348015610bb157600080fd5b50610bcc6004803603810190610bc7919061455e565b612088565b005b348015610bda57600080fd5b50610bf56004803603810190610bf09190613e8f565b6120d9565b005b348015610c0357600080fd5b50610c1e6004803603810190610c1991906140b5565b6120eb565b604051610c2b9190613ef5565b60405180910390f35b348015610c4057600080fd5b50610c5b6004803603810190610c569190613e8f565b61219a565b005b348015610c6957600080fd5b50610c846004803603810190610c7f9190613e8f565b6121f0565b604051610c919190613e37565b60405180910390f35b348015610ca657600080fd5b50610caf61226c565b604051610cbc9190614658565b60405180910390f35b348015610cd157600080fd5b50610cec6004803603810190610ce79190613f10565b61227f565b005b348015610cfa57600080fd5b50610d156004803603810190610d109190614248565b6122ec565b604051610d229190613ef5565b60405180910390f35b348015610d3757600080fd5b50610d40612335565b604051610d4d9190614682565b60405180910390f35b348015610d6257600080fd5b50610d7d6004803603810190610d78919061469d565b61233b565b604051610d8a9190613ef5565b60405180910390f35b348015610d9f57600080fd5b50610da8612384565b604051610db59190613ef5565b60405180910390f35b348015610dca57600080fd5b50610de56004803603810190610de091906146ca565b61238e565b604051610df29190613cbb565b60405180910390f35b348015610e0757600080fd5b50610e226004803603810190610e1d9190614248565b612422565b005b348015610e3057600080fd5b50610e4b6004803603810190610e469190613e8f565b6124a5565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610ea857506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610ed85750632a55205a60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610f085750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b610f176124ec565b81601d600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080601d60006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050565b606060038054610f9c90614739565b80601f0160208091040260200160405190810160405280929190818152602001828054610fc890614739565b80156110155780601f10610fea57610100808354040283529160200191611015565b820191906000526020600020905b815481529060010190602001808311610ff857829003601f168201915b5050505050905090565b6110276124ec565b8060178190555050565b600061103c8261256a565b611072576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60145481565b816110bd816125c9565b6110c783836126c6565b505050565b60135481565b60006110dc612807565b6002546001540303905090565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541161116b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611162906147dc565b60405180910390fd5b600061117682611d01565b9050600081036111bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111b29061486e565b60405180910390fd5b80600a60008282546111cd91906148bd565b9250508190555080600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061122b8282612810565b7fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056828260405161125c929190614912565b60405180910390a15050565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146112a6576112a5336125c9565b5b6112b1848484612904565b50505050565b600080601d600c9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166112e684611cb7565b915091509250929050565b60125481565b6000600954905090565b6000600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146113d8576113d7336125c9565b5b6113e3848484612c26565b50505050565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541161146b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611462906147dc565b60405180910390fd5b600061147783836120eb565b9050600081036114bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114b39061486e565b60405180910390fd5b80600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461150b91906148bd565b9250508190555080600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506115a7838383612c46565b8273ffffffffffffffffffffffffffffffffffffffff167f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a83836040516115ef92919061404e565b60405180910390a2505050565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff161461166a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161166190614987565b60405180910390fd5b6000601754905060016003811115611685576116846145e1565b5b601160009054906101000a900460ff1660038111156116a7576116a66145e1565b5b146116e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116de906149f3565b60405180910390fd5b6116f2338484612ccc565b611731576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172890614a5f565b60405180910390fd5b60165484601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461177f91906148bd565b11156117c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117b790614acb565b60405180910390fd5b601454846117cc6110d2565b6117d691906148bd565b1115611817576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180e90614b37565b60405180910390fd5b601254846118236110d2565b61182d91906148bd565b111561186e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186590614b37565b60405180910390fd5b838161187a9190614b57565b3410156118bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b390614be5565b60405180910390fd5b83601b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461190b91906148bd565b9250508190555061191c8585612d2a565b5050505050565b61192b6124ec565b8060158190555050565b61193d6124ec565b60005b601c5481101561196e5761195b61195682611b01565b6110e9565b808061196690614c05565b915050611940565b50565b600061197c82612d48565b9050919050565b60155481565b6010805461199690614739565b80601f01602080910402602001604051908101604052809291908181526020018280546119c290614739565b8015611a0f5780601f106119e457610100808354040283529160200191611a0f565b820191906000526020600020905b8154815290600101906020018083116119f257829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611a7e576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611ad76124ec565b611ae16000612e14565b565b60175481565b611af16124ec565b8060188190555050565b60165481565b6000600d8281548110611b1757611b16614c4d565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601a6020528060005260406000206000915090505481565b601b6020528060005260406000206000915090505481565b606060048054611bb190614739565b80601f0160208091040260200160405190810160405280929190818152602001828054611bdd90614739565b8015611c2a5780601f10611bff57610100808354040283529160200191611c2a565b820191906000526020600020905b815481529060010190602001808311611c0d57829003601f168201915b5050505050905090565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60185481565b611c8b6124ec565b8060109081611c9a9190614e1e565b5050565b81611ca8816125c9565b611cb28383612ed8565b505050565b6000601d60009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff1661271083611cf09190614f1f565b611cfa9190614b57565b9050919050565b600080611d0c612384565b47611d1791906148bd565b9050611d2c8382611d2786611c34565b61304f565b915050919050565b611d3c6124ec565b8060148190555050565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614611db4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dab90614987565b60405180910390fd5b6000601854905060008103611dfe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611df590614f9c565b60405180910390fd5b60026003811115611e1257611e116145e1565b5b601160009054906101000a900460ff166003811115611e3457611e336145e1565b5b14611e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e6b90615008565b60405180910390fd5b60135482611e806110d2565b611e8a91906148bd565b1115611ecb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec290614b37565b60405180910390fd5b60125482611ed76110d2565b611ee191906148bd565b1115611f22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1990614b37565b60405180910390fd5b60155482601a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611f7091906148bd565b1115611fb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa890614acb565b60405180910390fd5b8181611fbd9190614b57565b341015611fff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ff690614be5565b60405180910390fd5b81601a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461204e91906148bd565b9250508190555061205f8383612d2a565b505050565b61206c6124ec565b8060198190555050565b61207e6124ec565b8060138190555050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146120c6576120c5336125c9565b5b6120d2858585856130bd565b5050505050565b6120e16124ec565b8060168190555050565b6000806120f78461233b565b8473ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016121309190613ecb565b602060405180830381865afa15801561214d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612171919061503d565b61217b91906148bd565b9050612191838261218c8787611301565b61304f565b91505092915050565b6121a26124ec565b60125481106121e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121dd906150b6565b60405180910390fd5b8060128190555050565b60606121fb8261256a565b61223a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223190615122565b60405180910390fd5b601061224583613130565b60405160200161225692919061524d565b6040516020818303038152906040529050919050565b601160009054906101000a900460ff1681565b6122876124ec565b601254816122936110d2565b61229d91906148bd565b11156122de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d5906152c8565b60405180910390fd5b6122e88282612d2a565b5050565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60195481565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000600a54905090565b6000600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b61242a6124ec565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612499576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124909061535a565b60405180910390fd5b6124a281612e14565b50565b6124ad6124ec565b8060038111156124c0576124bf6145e1565b5b601160006101000a81548160ff021916908360038111156124e4576124e36145e1565b5b021790555050565b6124f46131fe565b73ffffffffffffffffffffffffffffffffffffffff16612512611b49565b73ffffffffffffffffffffffffffffffffffffffff1614612568576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161255f906153c6565b60405180910390fd5b565b600081612575612807565b11158015612584575060015482105b80156125c2575060007c0100000000000000000000000000000000000000000000000000000000600560008581526020019081526020016000205416145b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156126c3576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b81526004016126409291906153e6565b602060405180830381865afa15801561265d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126819190615424565b6126c257806040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016126b99190613ecb565b60405180910390fd5b5b50565b60006126d182611971565b90508073ffffffffffffffffffffffffffffffffffffffff166126f2613206565b73ffffffffffffffffffffffffffffffffffffffff16146127555761271e81612719613206565b61238e565b612754576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826007600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b80471015612853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161284a9061549d565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff1682604051612879906154ee565b60006040518083038185875af1925050503d80600081146128b6576040519150601f19603f3d011682016040523d82523d6000602084013e6128bb565b606091505b50509050806128ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128f690615575565b60405180910390fd5b505050565b600061290f82612d48565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612976576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806129828461320e565b915091506129988187612993613206565b613230565b6129e4576129ad866129a8613206565b61238e565b6129e3576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603612a4a576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a578686866001613274565b8015612a6257600082555b600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550612b3085612b0c88888761327a565b7c0200000000000000000000000000000000000000000000000000000000176132a2565b600560008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603612bb65760006001850190506000600560008381526020019081526020016000205403612bb4576001548114612bb3578360056000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612c1e86868660016132cd565b505050505050565b612c4183838360405180602001604052806000815250612088565b505050565b612cc78363a9059cbb60e01b8484604051602401612c6592919061404e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506132d3565b505050565b6000612d21612cda8561339a565b848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050506133ca565b90509392505050565b612d448282604051806020016040528060008152506133e1565b5050565b60008082905080612d57612807565b11612ddd57600154811015612ddc5760006005600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603612dda575b60008103612dd0576005600083600190039350838152602001908152602001600020549050612da6565b8092505050612e0f565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b612ee0613206565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612f44576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060086000612f51613206565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612ffe613206565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516130439190613cbb565b60405180910390a35050565b600081600954600b60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054856130a09190614b57565b6130aa9190614f1f565b6130b49190615595565b90509392505050565b6130c8848484611268565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461312a576130f38484848461347f565b613129576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b60606000600161313f846135cf565b01905060008167ffffffffffffffff81111561315e5761315d61427a565b5b6040519080825280601f01601f1916602001820160405280156131905781602001600182028036833780820191505090505b509050600082602001820190505b6001156131f3578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816131e7576131e6614ef0565b5b0494506000850361319e575b819350505050919050565b600033905090565b600033905090565b6000806000600790508360005280602052604060002092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8613291868684613722565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000613335826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661372b9092919063ffffffff16565b905060008151111561339557808060200190518101906133559190615424565b613394576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161338b9061563b565b60405180910390fd5b5b505050565b6000816040516020016133ad91906156a3565b604051602081830303815290604052805190602001209050919050565b60006133d98260195485613743565b905092915050565b6133eb838361375a565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461347a5760006001549050600083820390505b61342c600086838060010194508661347f565b613462576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81811061341957816001541461347757600080fd5b50505b505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026134a5613206565b8786866040518563ffffffff1660e01b81526004016134c79493929190615713565b6020604051808303816000875af192505050801561350357506040513d601f19601f820116820180604052508101906135009190615774565b60015b61357c573d8060008114613533576040519150601f19603f3d011682016040523d82523d6000602084013e613538565b606091505b506000815103613574576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061362d577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161362357613622614ef0565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061366a576d04ee2d6d415b85acef810000000083816136605761365f614ef0565b5b0492506020810190505b662386f26fc10000831061369957662386f26fc10000838161368f5761368e614ef0565b5b0492506010810190505b6305f5e10083106136c2576305f5e10083816136b8576136b7614ef0565b5b0492506008810190505b61271083106136e75761271083816136dd576136dc614ef0565b5b0492506004810190505b6064831061370a5760648381613700576136ff614ef0565b5b0492506002810190505b600a8310613719576001810190505b80915050919050565b60009392505050565b606061373a848460008561392d565b90509392505050565b60008261375085846139fa565b1490509392505050565b60006001549050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036137c7576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008203613801576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61380e6000848385613274565b600160406001901b178202600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061388583613876600086600061327a565b61387f85613a50565b176132a2565b60056000838152602001908152602001600020819055506000819050600083830190505b818060010192508573ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082106138a95780600181905550505061392860008483856132cd565b505050565b606082471015613972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161396990615813565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161399b9190615864565b60006040518083038185875af1925050503d80600081146139d8576040519150601f19603f3d011682016040523d82523d6000602084013e6139dd565b606091505b50915091506139ee87838387613a60565b92505050949350505050565b60008082905060005b8451811015613a4557613a3082868381518110613a2357613a22614c4d565b5b6020026020010151613ad5565b91508080613a3d90614c05565b915050613a03565b508091505092915050565b60006001821460e11b9050919050565b60608315613ac2576000835103613aba57613a7a85613b00565b613ab9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613ab0906158c7565b60405180910390fd5b5b829050613acd565b613acc8383613b23565b5b949350505050565b6000818310613aed57613ae88284613b73565b613af8565b613af78383613b73565b5b905092915050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600082511115613b365781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613b6a9190613e37565b60405180910390fd5b600082600052816020526040600020905092915050565b600082825260208201905092915050565b7f4f6e6c7920696620796f75206d696e7400000000000000000000000000000000600082015250565b6000613bd1601083613b8a565b9150613bdc82613b9b565b602082019050919050565b60006020820190508181036000830152613c0081613bc4565b9050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613c5081613c1b565b8114613c5b57600080fd5b50565b600081359050613c6d81613c47565b92915050565b600060208284031215613c8957613c88613c11565b5b6000613c9784828501613c5e565b91505092915050565b60008115159050919050565b613cb581613ca0565b82525050565b6000602082019050613cd06000830184613cac565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613d0182613cd6565b9050919050565b613d1181613cf6565b8114613d1c57600080fd5b50565b600081359050613d2e81613d08565b92915050565b60006bffffffffffffffffffffffff82169050919050565b613d5581613d34565b8114613d6057600080fd5b50565b600081359050613d7281613d4c565b92915050565b60008060408385031215613d8f57613d8e613c11565b5b6000613d9d85828601613d1f565b9250506020613dae85828601613d63565b9150509250929050565b600081519050919050565b60005b83811015613de1578082015181840152602081019050613dc6565b60008484015250505050565b6000601f19601f8301169050919050565b6000613e0982613db8565b613e138185613b8a565b9350613e23818560208601613dc3565b613e2c81613ded565b840191505092915050565b60006020820190508181036000830152613e518184613dfe565b905092915050565b6000819050919050565b613e6c81613e59565b8114613e7757600080fd5b50565b600081359050613e8981613e63565b92915050565b600060208284031215613ea557613ea4613c11565b5b6000613eb384828501613e7a565b91505092915050565b613ec581613cf6565b82525050565b6000602082019050613ee06000830184613ebc565b92915050565b613eef81613e59565b82525050565b6000602082019050613f0a6000830184613ee6565b92915050565b60008060408385031215613f2757613f26613c11565b5b6000613f3585828601613d1f565b9250506020613f4685828601613e7a565b9150509250929050565b6000613f5b82613cd6565b9050919050565b613f6b81613f50565b8114613f7657600080fd5b50565b600081359050613f8881613f62565b92915050565b600060208284031215613fa457613fa3613c11565b5b6000613fb284828501613f79565b91505092915050565b600080600060608486031215613fd457613fd3613c11565b5b6000613fe286828701613d1f565b9350506020613ff386828701613d1f565b925050604061400486828701613e7a565b9150509250925092565b6000806040838503121561402557614024613c11565b5b600061403385828601613e7a565b925050602061404485828601613e7a565b9150509250929050565b60006040820190506140636000830185613ebc565b6140706020830184613ee6565b9392505050565b600061408282613cf6565b9050919050565b61409281614077565b811461409d57600080fd5b50565b6000813590506140af81614089565b92915050565b600080604083850312156140cc576140cb613c11565b5b60006140da858286016140a0565b92505060206140eb85828601613d1f565b9150509250929050565b6000819050919050565b600061411a61411561411084613cd6565b6140f5565b613cd6565b9050919050565b600061412c826140ff565b9050919050565b600061413e82614121565b9050919050565b61414e81614133565b82525050565b60006020820190506141696000830184614145565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126141945761419361416f565b5b8235905067ffffffffffffffff8111156141b1576141b0614174565b5b6020830191508360208202830111156141cd576141cc614179565b5b9250929050565b600080600080606085870312156141ee576141ed613c11565b5b60006141fc87828801613d1f565b945050602061420d87828801613e7a565b935050604085013567ffffffffffffffff81111561422e5761422d613c16565b5b61423a8782880161417e565b925092505092959194509250565b60006020828403121561425e5761425d613c11565b5b600061426c84828501613d1f565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6142b282613ded565b810181811067ffffffffffffffff821117156142d1576142d061427a565b5b80604052505050565b60006142e4613c07565b90506142f082826142a9565b919050565b600067ffffffffffffffff8211156143105761430f61427a565b5b61431982613ded565b9050602081019050919050565b82818337600083830152505050565b6000614348614343846142f5565b6142da565b90508281526020810184848401111561436457614363614275565b5b61436f848285614326565b509392505050565b600082601f83011261438c5761438b61416f565b5b813561439c848260208601614335565b91505092915050565b6000602082840312156143bb576143ba613c11565b5b600082013567ffffffffffffffff8111156143d9576143d8613c16565b5b6143e584828501614377565b91505092915050565b6143f781613ca0565b811461440257600080fd5b50565b600081359050614414816143ee565b92915050565b6000806040838503121561443157614430613c11565b5b600061443f85828601613d1f565b925050602061445085828601614405565b9150509250929050565b6000819050919050565b61446d8161445a565b811461447857600080fd5b50565b60008135905061448a81614464565b92915050565b6000602082840312156144a6576144a5613c11565b5b60006144b48482850161447b565b91505092915050565b600067ffffffffffffffff8211156144d8576144d761427a565b5b6144e182613ded565b9050602081019050919050565b60006145016144fc846144bd565b6142da565b90508281526020810184848401111561451d5761451c614275565b5b614528848285614326565b509392505050565b600082601f8301126145455761454461416f565b5b81356145558482602086016144ee565b91505092915050565b6000806000806080858703121561457857614577613c11565b5b600061458687828801613d1f565b945050602061459787828801613d1f565b93505060406145a887828801613e7a565b925050606085013567ffffffffffffffff8111156145c9576145c8613c16565b5b6145d587828801614530565b91505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110614621576146206145e1565b5b50565b600081905061463282614610565b919050565b600061464282614624565b9050919050565b61465281614637565b82525050565b600060208201905061466d6000830184614649565b92915050565b61467c8161445a565b82525050565b60006020820190506146976000830184614673565b92915050565b6000602082840312156146b3576146b2613c11565b5b60006146c1848285016140a0565b91505092915050565b600080604083850312156146e1576146e0613c11565b5b60006146ef85828601613d1f565b925050602061470085828601613d1f565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061475157607f821691505b6020821081036147645761476361470a565b5b50919050565b7f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060008201527f7368617265730000000000000000000000000000000000000000000000000000602082015250565b60006147c6602683613b8a565b91506147d18261476a565b604082019050919050565b600060208201905081810360008301526147f5816147b9565b9050919050565b7f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060008201527f647565207061796d656e74000000000000000000000000000000000000000000602082015250565b6000614858602b83613b8a565b9150614863826147fc565b604082019050919050565b600060208201905081810360008301526148878161484b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006148c882613e59565b91506148d383613e59565b92508282019050808211156148eb576148ea61488e565b5b92915050565b60006148fc82614121565b9050919050565b61490c816148f1565b82525050565b60006040820190506149276000830185614903565b6149346020830184613ee6565b9392505050565b7f5468652063616c6c657220697320616e6f7468657220636f6e74726163740000600082015250565b6000614971601e83613b8a565b915061497c8261493b565b602082019050919050565b600060208201905081810360008301526149a081614964565b9050919050565b7f57686974656c6973742073616c65206973206e6f742061637469766174656400600082015250565b60006149dd601f83613b8a565b91506149e8826149a7565b602082019050919050565b60006020820190508181036000830152614a0c816149d0565b9050919050565b7f4e6f742077686974656c69737465640000000000000000000000000000000000600082015250565b6000614a49600f83613b8a565b9150614a5482614a13565b602082019050919050565b60006020820190508181036000830152614a7881614a3c565b9050919050565b7f4d6178207065722077616c6c6574206c696d6974207265616368656400000000600082015250565b6000614ab5601c83613b8a565b9150614ac082614a7f565b602082019050919050565b60006020820190508181036000830152614ae481614aa8565b9050919050565b7f4d617820737570706c7920657863656564656400000000000000000000000000600082015250565b6000614b21601383613b8a565b9150614b2c82614aeb565b602082019050919050565b60006020820190508181036000830152614b5081614b14565b9050919050565b6000614b6282613e59565b9150614b6d83613e59565b9250828202614b7b81613e59565b91508282048414831517614b9257614b9161488e565b5b5092915050565b7f4e6f7420656e6f756768742066756e6473000000000000000000000000000000600082015250565b6000614bcf601183613b8a565b9150614bda82614b99565b602082019050919050565b60006020820190508181036000830152614bfe81614bc2565b9050919050565b6000614c1082613e59565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614c4257614c4161488e565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302614cde7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614ca1565b614ce88683614ca1565b95508019841693508086168417925050509392505050565b6000614d1b614d16614d1184613e59565b6140f5565b613e59565b9050919050565b6000819050919050565b614d3583614d00565b614d49614d4182614d22565b848454614cae565b825550505050565b600090565b614d5e614d51565b614d69818484614d2c565b505050565b5b81811015614d8d57614d82600082614d56565b600181019050614d6f565b5050565b601f821115614dd257614da381614c7c565b614dac84614c91565b81016020851015614dbb578190505b614dcf614dc785614c91565b830182614d6e565b50505b505050565b600082821c905092915050565b6000614df560001984600802614dd7565b1980831691505092915050565b6000614e0e8383614de4565b9150826002028217905092915050565b614e2782613db8565b67ffffffffffffffff811115614e4057614e3f61427a565b5b614e4a8254614739565b614e55828285614d91565b600060209050601f831160018114614e885760008415614e76578287015190505b614e808582614e02565b865550614ee8565b601f198416614e9686614c7c565b60005b82811015614ebe57848901518255600182019150602085019450602081019050614e99565b86831015614edb5784890151614ed7601f891682614de4565b8355505b6001600288020188555050505b505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614f2a82613e59565b9150614f3583613e59565b925082614f4557614f44614ef0565b5b828204905092915050565b7f5072696365206973203000000000000000000000000000000000000000000000600082015250565b6000614f86600a83613b8a565b9150614f9182614f50565b602082019050919050565b60006020820190508181036000830152614fb581614f79565b9050919050565b7f5075626c69632073616c65206973206e6f742061637469766174656400000000600082015250565b6000614ff2601c83613b8a565b9150614ffd82614fbc565b602082019050919050565b6000602082019050818103600083015261502181614fe5565b9050919050565b60008151905061503781613e63565b92915050565b60006020828403121561505357615052613c11565b5b600061506184828501615028565b91505092915050565b7f43616e6e6f7420696e63726561736520737570706c7921000000000000000000600082015250565b60006150a0601783613b8a565b91506150ab8261506a565b602082019050919050565b600060208201905081810360008301526150cf81615093565b9050919050565b7f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e00600082015250565b600061510c601f83613b8a565b9150615117826150d6565b602082019050919050565b6000602082019050818103600083015261513b816150ff565b9050919050565b600081905092915050565b6000815461515a81614739565b6151648186615142565b9450600182166000811461517f5760018114615194576151c7565b60ff19831686528115158202860193506151c7565b61519d85614c7c565b60005b838110156151bf578154818901526001820191506020810190506151a0565b838801955050505b50505092915050565b60006151db82613db8565b6151e58185615142565b93506151f5818560208601613dc3565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000615237600583615142565b915061524282615201565b600582019050919050565b6000615259828561514d565b915061526582846151d0565b91506152708261522a565b91508190509392505050565b7f52656163686564206d617820537570706c790000000000000000000000000000600082015250565b60006152b2601283613b8a565b91506152bd8261527c565b602082019050919050565b600060208201905081810360008301526152e1816152a5565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615344602683613b8a565b915061534f826152e8565b604082019050919050565b6000602082019050818103600083015261537381615337565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006153b0602083613b8a565b91506153bb8261537a565b602082019050919050565b600060208201905081810360008301526153df816153a3565b9050919050565b60006040820190506153fb6000830185613ebc565b6154086020830184613ebc565b9392505050565b60008151905061541e816143ee565b92915050565b60006020828403121561543a57615439613c11565b5b60006154488482850161540f565b91505092915050565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b6000615487601d83613b8a565b915061549282615451565b602082019050919050565b600060208201905081810360008301526154b68161547a565b9050919050565b600081905092915050565b50565b60006154d86000836154bd565b91506154e3826154c8565b600082019050919050565b60006154f9826154cb565b9150819050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b600061555f603a83613b8a565b915061556a82615503565b604082019050919050565b6000602082019050818103600083015261558e81615552565b9050919050565b60006155a082613e59565b91506155ab83613e59565b92508282039050818111156155c3576155c261488e565b5b92915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000615625602a83613b8a565b9150615630826155c9565b604082019050919050565b6000602082019050818103600083015261565481615618565b9050919050565b60008160601b9050919050565b60006156738261565b565b9050919050565b600061568582615668565b9050919050565b61569d61569882613cf6565b61567a565b82525050565b60006156af828461568c565b60148201915081905092915050565b600081519050919050565b600082825260208201905092915050565b60006156e5826156be565b6156ef81856156c9565b93506156ff818560208601613dc3565b61570881613ded565b840191505092915050565b60006080820190506157286000830187613ebc565b6157356020830186613ebc565b6157426040830185613ee6565b818103606083015261575481846156da565b905095945050505050565b60008151905061576e81613c47565b92915050565b60006020828403121561578a57615789613c11565b5b60006157988482850161575f565b91505092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006157fd602683613b8a565b9150615808826157a1565b604082019050919050565b6000602082019050818103600083015261582c816157f0565b9050919050565b600061583e826156be565b61584881856154bd565b9350615858818560208601613dc3565b80840191505092915050565b60006158708284615833565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006158b1601d83613b8a565b91506158bc8261587b565b602082019050919050565b600060208201905081810360008301526158e0816158a4565b905091905056fea2646970667358221220407d7ffd3c55490253a534f3b92cb9204f804d64bd474ea7b48161e4c0fcd09164736f6c63430008110033

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

00000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e068a09eb3cb3252fa5655f26180ac67bd2972a02533771890d77b679aecfd481300000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000b3eb7ada0ea10f007e0380d26e65e26e598539b6000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000043697066733a2f2f6261667962656965776e79783237377777696f33706e3632716e67617273776d346e65646a6e6370613273637777616b346f656b61723674776b712f0000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _royaltyFeesInBips (uint96): 1000
Arg [1] : _team (address[]): 0xb3eb7aDA0ea10F007E0380d26E65e26E598539B6
Arg [2] : _teamShares (uint256[]): 100
Arg [3] : _merkleRootWL (bytes32): 0x68a09eb3cb3252fa5655f26180ac67bd2972a02533771890d77b679aecfd4813
Arg [4] : _baseURI (string): ipfs://bafybeiewnyx277wwio3pn62qngarswm4nedjncpa2scwwak4oekar6twkq/

-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000003e8
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [3] : 68a09eb3cb3252fa5655f26180ac67bd2972a02533771890d77b679aecfd4813
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [6] : 000000000000000000000000b3eb7ada0ea10f007e0380d26e65e26e598539b6
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000043
Arg [10] : 697066733a2f2f6261667962656965776e79783237377777696f33706e363271
Arg [11] : 6e67617273776d346e65646a6e6370613273637777616b346f656b6172367477
Arg [12] : 6b712f0000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

106472:6922:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;113355:26;;;;;;;;;;:::i;:::-;;;;;;;;106472:6922;;;;14582:678;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;112007:183;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;20292:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;110294:107;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;22244:204;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;106835:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;112382:157;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;106793:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;13636:315;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100868:671;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;112547:163;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;111609:242;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;106757:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98478:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99607:135;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47674:143;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;112718:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;101807:792;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;107863:770;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;110142:144;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113149:151;;;;;;;;;;;;;:::i;:::-;;20081:144;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;106877:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;106695:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;15324:224;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105580:103;;;;;;;;;;;;;:::i;:::-;;106967:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;110409:123;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;106923:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99833:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104932:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;107098:57;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;107162:53;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;20461:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99329:109;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;107010:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;110540:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;112198:176;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;111859:140;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100023:225;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109889:109;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;108643:730;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;111022:114;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;109756:125;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;112895:228;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;110006:128;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;100408:260;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109576:172;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;110748:249;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;106725:23;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;109381:187;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;99125:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;107060:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98915:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98663:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22903:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105838:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;110648:92;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;14582:678;14667:4;14982:10;14967:25;;:11;:25;;;;:102;;;;15059:10;15044:25;;:11;:25;;;;14967:102;:179;;;;15136:10;15121:25;;:11;:25;;;;14967:179;:242;;;;15199:10;15184:25;;:11;:25;;;;14967:242;14947:262;;14582:678;;;:::o;112007:183::-;104818:13;:11;:13::i;:::-;112124:9:::1;112106:15;;:27;;;;;;;;;;;;;;;;;;112164:18;112144:17;;:38;;;;;;;;;;;;;;;;;;112007:183:::0;;:::o;20292:100::-;20346:13;20379:5;20372:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20292:100;:::o;110294:107::-;104818:13;:11;:13::i;:::-;110381:12:::1;110367:11;:26;;;;110294:107:::0;:::o;22244:204::-;22312:7;22337:16;22345:7;22337;:16::i;:::-;22332:64;;22362:34;;;;;;;;;;;;;;22332:64;22416:15;:24;22432:7;22416:24;;;;;;;;;;;;;;;;;;;;;22409:31;;22244:204;;;:::o;106835:31::-;;;;:::o;112382:157::-;112478:8;49195:30;49216:8;49195:20;:30::i;:::-;112499:32:::1;112513:8;112523:7;112499:13;:32::i;:::-;112382:157:::0;;;:::o;106793:35::-;;;;:::o;13636:315::-;13689:7;13917:15;:13;:15::i;:::-;13902:12;;13886:13;;:28;:46;13879:53;;13636:315;:::o;100868:671::-;100963:1;100944:7;:16;100952:7;100944:16;;;;;;;;;;;;;;;;:20;100936:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;101020:15;101038:19;101049:7;101038:10;:19::i;:::-;101020:37;;101089:1;101078:7;:12;101070:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;101351:7;101333:14;;:25;;;;;;;:::i;:::-;;;;;;;;101416:7;101394:9;:18;101404:7;101394:18;;;;;;;;;;;;;;;;:29;;;;;;;;;;;101447:35;101465:7;101474;101447:17;:35::i;:::-;101498:33;101514:7;101523;101498:33;;;;;;;:::i;:::-;;;;;;;;100925:614;100868:671;:::o;112547:163::-;112648:4;49023:10;49015:18;;:4;:18;;;49011:83;;49050:32;49071:10;49050:20;:32::i;:::-;49011:83;112665:37:::1;112684:4;112690:2;112694:7;112665:18;:37::i;:::-;112547:163:::0;;;;:::o;111609:242::-;111720:16;111747:21;111796:15;;;;;;;;;;;111813:28;111830:10;111813:16;:28::i;:::-;111788:54;;;;111609:242;;;;;:::o;106757:29::-;;;;:::o;98478:91::-;98522:7;98549:12;;98542:19;;98478:91;:::o;99607:135::-;99677:7;99704:14;:21;99719:5;99704:21;;;;;;;;;;;;;;;:30;99726:7;99704:30;;;;;;;;;;;;;;;;99697:37;;99607:135;;;;:::o;47674:143::-;47774:42;47674:143;:::o;112718:171::-;112823:4;49023:10;49015:18;;:4;:18;;;49011:83;;49050:32;49071:10;49050:20;:32::i;:::-;49011:83;112840:41:::1;112863:4;112869:2;112873:7;112840:22;:41::i;:::-;112718:171:::0;;;;:::o;101807:792::-;101908:1;101889:7;:16;101897:7;101889:16;;;;;;;;;;;;;;;;:20;101881:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;101965:15;101983:26;101994:5;102001:7;101983:10;:26::i;:::-;101965:44;;102041:1;102030:7;:12;102022:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;102375:7;102345:19;:26;102365:5;102345:26;;;;;;;;;;;;;;;;:37;;;;;;;:::i;:::-;;;;;;;;102452:7;102418:14;:21;102433:5;102418:21;;;;;;;;;;;;;;;:30;102440:7;102418:30;;;;;;;;;;;;;;;;:41;;;;;;;;;;;102483:47;102506:5;102513:7;102522;102483:22;:47::i;:::-;102567:5;102546:45;;;102574:7;102583;102546:45;;;;;;;:::i;:::-;;;;;;;;101870:729;101807:792;;:::o;107863:770::-;107791:10;107778:23;;:9;:23;;;107770:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;107988:10:::1;108001:11;;107988:24;;108046:18;108031:33;;;;;;;;:::i;:::-;;:11;;;;;;;;;;;:33;;;;;;;;:::i;:::-;;;108023:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;108119:33;108133:10;108145:6;;108119:13;:33::i;:::-;108111:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;108240:17;;108227:9;108191:21;:33;108213:10;108191:33;;;;;;;;;;;;;;;;:45;;;;:::i;:::-;:66;;108183:107;;;;;;;;;;;;:::i;:::-;;;;;;;;;108338:12;;108325:9;108309:13;:11;:13::i;:::-;:25;;;;:::i;:::-;:41;;108301:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;108422:10;;108409:9;108393:13;:11;:13::i;:::-;:25;;;;:::i;:::-;:39;;108385:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;108496:9;108488:5;:17;;;;:::i;:::-;108475:9;:30;;108467:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;108575:9;108538:21;:33;108560:10;108538:33;;;;;;;;;;;;;;;;:46;;;;;;;:::i;:::-;;;;;;;;108595:30;108605:8;108615:9;108595;:30::i;:::-;107977:656;107863:770:::0;;;;:::o;110142:144::-;104818:13;:11;:13::i;:::-;110256:22:::1;110232:21;:46;;;;110142:144:::0;:::o;113149:151::-;104818:13;:11;:13::i;:::-;113205:6:::1;113201:92;113222:10;;113218:1;:14;113201:92;;;113255:26;113271:8;113277:1;113271:5;:8::i;:::-;113255:7;:26::i;:::-;113235:3;;;;;:::i;:::-;;;;113201:92;;;;113149:151::o:0;20081:144::-;20145:7;20188:27;20207:7;20188:18;:27::i;:::-;20165:52;;20081:144;;;:::o;106877:39::-;;;;:::o;106695:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;15324:224::-;15388:7;15429:1;15412:19;;:5;:19;;;15408:60;;15440:28;;;;;;;;;;;;;;15408:60;9816:13;15486:18;:25;15505:5;15486:25;;;;;;;;;;;;;;;;:54;15479:61;;15324:224;;;:::o;105580:103::-;104818:13;:11;:13::i;:::-;105645:30:::1;105672:1;105645:18;:30::i;:::-;105580:103::o:0;106967:36::-;;;;:::o;110409:123::-;104818:13;:11;:13::i;:::-;110508:16:::1;110490:15;:34;;;;110409:123:::0;:::o;106923:33::-;;;;:::o;99833:100::-;99884:7;99911;99919:5;99911:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;99904:21;;99833:100;;;:::o;104932:87::-;104978:7;105005:6;;;;;;;;;;;104998:13;;104932:87;:::o;107098:57::-;;;;;;;;;;;;;;;;;:::o;107162:53::-;;;;;;;;;;;;;;;;;:::o;20461:104::-;20517:13;20550:7;20543:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20461:104;:::o;99329:109::-;99385:7;99412:9;:18;99422:7;99412:18;;;;;;;;;;;;;;;;99405:25;;99329:109;;;:::o;107010:41::-;;;;:::o;110540:100::-;104818:13;:11;:13::i;:::-;110624:8:::1;110614:7;:18;;;;;;:::i;:::-;;110540:100:::0;:::o;112198:176::-;112302:8;49195:30;49216:8;49195:20;:30::i;:::-;112323:43:::1;112347:8;112357;112323:23;:43::i;:::-;112198:176:::0;;;:::o;111859:140::-;111926:7;111974:17;;;;;;;;;;;111951:40;;111965:5;111952:10;:18;;;;:::i;:::-;111951:40;;;;:::i;:::-;111945:46;;111859:140;;;:::o;100023:225::-;100081:7;100101:21;100149:15;:13;:15::i;:::-;100125:21;:39;;;;:::i;:::-;100101:63;;100182:58;100198:7;100207:13;100222:17;100231:7;100222:8;:17::i;:::-;100182:15;:58::i;:::-;100175:65;;;100023:225;;;:::o;109889:109::-;104818:13;:11;:13::i;:::-;109977::::1;109962:12;:28;;;;109889:109:::0;:::o;108643:730::-;107791:10;107778:23;;:9;:23;;;107770:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;108742:10:::1;108755:15;;108742:28;;108798:1;108789:5;:10:::0;108781:33:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;108848:15;108833:30;;;;;;;;:::i;:::-;;:11;;;;;;;;;;;:30;;;;;;;;:::i;:::-;;;108825:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;108944:16;;108931:9;108915:13;:11;:13::i;:::-;:25;;;;:::i;:::-;:45;;108907:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;109032:10;;109019:9;109003:13;:11;:13::i;:::-;:25;;;;:::i;:::-;:39;;108995:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;109138:21;;109125:9;109085:25;:37;109111:10;109085:37;;;;;;;;;;;;;;;;:49;;;;:::i;:::-;:74;;109077:115;;;;;;;;;;;;:::i;:::-;;;;;;;;;109232:9;109224:5;:17;;;;:::i;:::-;109211:9;:30;;109203:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;109315:9;109274:25;:37;109300:10;109274:37;;;;;;;;;;;;;;;;:50;;;;;;;:::i;:::-;;;;;;;;109335:30;109345:8;109355:9;109335;:30::i;:::-;108731:642;108643:730:::0;;:::o;111022:114::-;104818:13;:11;:13::i;:::-;111115::::1;111100:12;:28;;;;111022:114:::0;:::o;109756:125::-;104818:13;:11;:13::i;:::-;109856:17:::1;109837:16;:36;;;;109756:125:::0;:::o;112895:228::-;113046:4;49023:10;49015:18;;:4;:18;;;49011:83;;49050:32;49071:10;49050:20;:32::i;:::-;49011:83;113068:47:::1;113091:4;113097:2;113101:7;113110:4;113068:22;:47::i;:::-;112895:228:::0;;;;;:::o;110006:128::-;104818:13;:11;:13::i;:::-;110108:18:::1;110088:17;:38;;;;110006:128:::0;:::o;100408:260::-;100480:7;100500:21;100557:20;100571:5;100557:13;:20::i;:::-;100524:5;:15;;;100548:4;100524:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;;;:::i;:::-;100500:77;;100595:65;100611:7;100620:13;100635:24;100644:5;100651:7;100635:8;:24::i;:::-;100595:15;:65::i;:::-;100588:72;;;100408:260;;;;:::o;109576:172::-;104818:13;:11;:13::i;:::-;109667:10:::1;;109653:11;:24;109645:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;109729:11;109716:10;:24;;;;109576:172:::0;:::o;110748:249::-;110819:13;110853:17;110861:8;110853:7;:17::i;:::-;110845:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;110950:7;110959:19;:8;:17;:19::i;:::-;110933:55;;;;;;;;;:::i;:::-;;;;;;;;;;;;;110919:70;;110748:249;;;:::o;106725:23::-;;;;;;;;;;;;;:::o;109381:187::-;104818:13;:11;:13::i;:::-;109491:10:::1;;109478:9;109462:13;:11;:13::i;:::-;:25;;;;:::i;:::-;:39;;109454:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;109535:25;109545:3;109550:9;109535;:25::i;:::-;109381:187:::0;;:::o;99125:105::-;99179:7;99206;:16;99214:7;99206:16;;;;;;;;;;;;;;;;99199:23;;99125:105;;;:::o;107060:27::-;;;;:::o;98915:119::-;98973:7;99000:19;:26;99020:5;99000:26;;;;;;;;;;;;;;;;98993:33;;98915:119;;;:::o;98663:95::-;98709:7;98736:14;;98729:21;;98663:95;:::o;22903:164::-;23000:4;23024:18;:25;23043:5;23024:25;;;;;;;;;;;;;;;:35;23050:8;23024:35;;;;;;;;;;;;;;;;;;;;;;;;;23017:42;;22903:164;;;;:::o;105838:201::-;104818:13;:11;:13::i;:::-;105947:1:::1;105927:22;;:8;:22;;::::0;105919:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;106003:28;106022:8;106003:18;:28::i;:::-;105838:201:::0;:::o;110648:92::-;104818:13;:11;:13::i;:::-;110726:5:::1;110721:11;;;;;;;;:::i;:::-;;110707;;:25;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;110648:92:::0;:::o;105097:132::-;105172:12;:10;:12::i;:::-;105161:23;;:7;:5;:7::i;:::-;:23;;;105153:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;105097:132::o;24048:273::-;24105:4;24161:7;24142:15;:13;:15::i;:::-;:26;;:66;;;;;24195:13;;24185:7;:23;24142:66;:152;;;;;24293:1;10586:8;24246:17;:26;24264:7;24246:26;;;;;;;;;;;;:43;:48;24142:152;24122:172;;24048:273;;;:::o;49253:419::-;49492:1;47774:42;49444:45;;;:49;49440:225;;;47774:42;49515;;;49566:4;49573:8;49515:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49510:144;;49629:8;49610:28;;;;;;;;;;;:::i;:::-;;;;;;;;49510:144;49440:225;49253:419;:::o;21786:392::-;21867:13;21883:16;21891:7;21883;:16::i;:::-;21867:32;;21937:5;21914:28;;:19;:17;:19::i;:::-;:28;;;21910:175;;21962:44;21979:5;21986:19;:17;:19::i;:::-;21962:16;:44::i;:::-;21957:128;;22034:35;;;;;;;;;;;;;;21957:128;21910:175;22124:2;22097:15;:24;22113:7;22097:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;22162:7;22158:2;22142:28;;22151:5;22142:28;;;;;;;;;;;;21856:322;21786:392;;:::o;13160:92::-;13216:7;13243:1;13236:8;;13160:92;:::o;67846:317::-;67961:6;67936:21;:31;;67928:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;68015:12;68033:9;:14;;68055:6;68033:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68014:52;;;68085:7;68077:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;67917:246;67846:317;;:::o;31513:2800::-;31647:27;31677;31696:7;31677:18;:27::i;:::-;31647:57;;31762:4;31721:45;;31737:19;31721:45;;;31717:86;;31775:28;;;;;;;;;;;;;;31717:86;31817:27;31846:23;31873:28;31893:7;31873:19;:28::i;:::-;31816:85;;;;32001:62;32020:15;32037:4;32043:19;:17;:19::i;:::-;32001:18;:62::i;:::-;31996:174;;32083:43;32100:4;32106:19;:17;:19::i;:::-;32083:16;:43::i;:::-;32078:92;;32135:35;;;;;;;;;;;;;;32078:92;31996:174;32201:1;32187:16;;:2;:16;;;32183:52;;32212:23;;;;;;;;;;;;;;32183:52;32248:43;32270:4;32276:2;32280:7;32289:1;32248:21;:43::i;:::-;32384:15;32381:160;;;32524:1;32503:19;32496:30;32381:160;32919:18;:24;32938:4;32919:24;;;;;;;;;;;;;;;;32917:26;;;;;;;;;;;;32988:18;:22;33007:2;32988:22;;;;;;;;;;;;;;;;32986:24;;;;;;;;;;;33310:145;33347:2;33395:45;33410:4;33416:2;33420:19;33395:14;:45::i;:::-;10864:8;33368:72;33310:18;:145::i;:::-;33281:17;:26;33299:7;33281:26;;;;;;;;;;;:174;;;;33625:1;10864:8;33575:19;:46;:51;33571:626;;33647:19;33679:1;33669:7;:11;33647:33;;33836:1;33802:17;:30;33820:11;33802:30;;;;;;;;;;;;:35;33798:384;;33940:13;;33925:11;:28;33921:242;;34120:19;34087:17;:30;34105:11;34087:30;;;;;;;;;;;:52;;;;33921:242;33798:384;33628:569;33571:626;34244:7;34240:2;34225:27;;34234:4;34225:27;;;;;;;;;;;;34263:42;34284:4;34290:2;34294:7;34303:1;34263:20;:42::i;:::-;31636:2677;;;31513:2800;;;:::o;23138:185::-;23276:39;23293:4;23299:2;23303:7;23276:39;;;;;;;;;;;;:16;:39::i;:::-;23138:185;;;:::o;80738:211::-;80855:86;80875:5;80905:23;;;80930:2;80934:5;80882:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80855:19;:86::i;:::-;80738:211;;;:::o;111144:155::-;111234:4;111258:33;111268:14;111273:8;111268:4;:14::i;:::-;111284:6;;111258:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:9;:33::i;:::-;111251:40;;111144:155;;;;;:::o;24405:104::-;24474:27;24484:2;24488:8;24474:27;;;;;;;;;;;;:9;:27::i;:::-;24405:104;;:::o;16998:1129::-;17065:7;17085:12;17100:7;17085:22;;17168:4;17149:15;:13;:15::i;:::-;:23;17145:915;;17202:13;;17195:4;:20;17191:869;;;17240:14;17257:17;:23;17275:4;17257:23;;;;;;;;;;;;17240:40;;17373:1;10586:8;17346:6;:23;:28;17342:699;;17865:113;17882:1;17872:6;:11;17865:113;;17925:17;:25;17943:6;;;;;;;17925:25;;;;;;;;;;;;17916:34;;17865:113;;;18011:6;18004:13;;;;;;17342:699;17217:843;17191:869;17145:915;18088:31;;;;;;;;;;;;;;16998:1129;;;;:::o;106199:191::-;106273:16;106292:6;;;;;;;;;;;106273:25;;106318:8;106309:6;;:17;;;;;;;;;;;;;;;;;;106373:8;106342:40;;106363:8;106342:40;;;;;;;;;;;;106262:128;106199:191;:::o;22520:306::-;22631:19;:17;:19::i;:::-;22619:31;;:8;:31;;;22615:61;;22659:17;;;;;;;;;;;;;;22615:61;22739:8;22687:18;:39;22706:19;:17;:19::i;:::-;22687:39;;;;;;;;;;;;;;;:49;22727:8;22687:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;22799:8;22763:55;;22778:19;:17;:19::i;:::-;22763:55;;;22809:8;22763:55;;;;;;:::i;:::-;;;;;;;;22520:306;;:::o;102777:248::-;102923:7;103002:15;102987:12;;102967:7;:16;102975:7;102967:16;;;;;;;;;;;;;;;;102951:13;:32;;;;:::i;:::-;102950:49;;;;:::i;:::-;:67;;;;:::i;:::-;102943:74;;102777:248;;;;;:::o;23394:399::-;23561:31;23574:4;23580:2;23584:7;23561:12;:31::i;:::-;23625:1;23607:2;:14;;;:19;23603:183;;23646:56;23677:4;23683:2;23687:7;23696:5;23646:30;:56::i;:::-;23641:145;;23730:40;;;;;;;;;;;;;;23641:145;23603:183;23394:399;;;;:::o;63458:716::-;63514:13;63565:14;63602:1;63582:17;63593:5;63582:10;:17::i;:::-;:21;63565:38;;63618:20;63652:6;63641:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63618:41;;63674:11;63803:6;63799:2;63795:15;63787:6;63783:28;63776:35;;63840:288;63847:4;63840:288;;;63872:5;;;;;;;;64014:8;64009:2;64002:5;63998:14;63993:30;63988:3;63980:44;64070:2;64061:11;;;;;;:::i;:::-;;;;;64104:1;64095:5;:10;63840:288;64091:21;63840:288;64149:6;64142:13;;;;;63458:716;;;:::o;94768:98::-;94821:7;94848:10;94841:17;;94768:98;:::o;42609:105::-;42669:7;42696:10;42689:17;;42609:105;:::o;29849:652::-;29944:27;29973:23;30014:53;30070:15;30014:71;;30256:7;30250:4;30243:21;30291:22;30285:4;30278:36;30367:4;30361;30351:21;30328:44;;30463:19;30457:26;30438:45;;30194:300;29849:652;;;:::o;30614:645::-;30756:11;30918:15;30912:4;30908:26;30900:34;;31077:15;31066:9;31062:31;31049:44;;31224:15;31213:9;31210:30;31203:4;31192:9;31189:19;31186:55;31176:65;;30614:645;;;;;:::o;41442:159::-;;;;;:::o;39754:309::-;39889:7;39909:16;10987:3;39935:19;:40;;39909:67;;10987:3;40002:31;40013:4;40019:2;40023:9;40002:10;:31::i;:::-;39994:40;;:61;;39987:68;;;39754:309;;;;;:::o;19572:447::-;19652:14;19820:15;19813:5;19809:27;19800:36;;19994:5;19980:11;19956:22;19952:40;19949:51;19942:5;19939:62;19929:72;;19572:447;;;;:::o;42260:158::-;;;;;:::o;83805:716::-;84229:23;84255:69;84283:4;84255:69;;;;;;;;;;;;;;;;;84263:5;84255:27;;;;:69;;;;;:::i;:::-;84229:95;;84359:1;84339:10;:17;:21;84335:179;;;84436:10;84425:30;;;;;;;;;;;;:::i;:::-;84417:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;84335:179;83875:646;83805:716;;:::o;111307:126::-;111361:7;111415:8;111398:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;111388:37;;;;;;111381:44;;111307:126;;;:::o;111441:160::-;111522:4;111546:47;111565:6;111573:12;;111587:5;111546:18;:47::i;:::-;111539:54;;111441:160;;;;:::o;24925:681::-;25048:19;25054:2;25058:8;25048:5;:19::i;:::-;25127:1;25109:2;:14;;;:19;25105:483;;25149:11;25163:13;;25149:27;;25195:13;25217:8;25211:3;:14;25195:30;;25244:233;25275:62;25314:1;25318:2;25322:7;;;;;;25331:5;25275:30;:62::i;:::-;25270:167;;25373:40;;;;;;;;;;;;;;25270:167;25472:3;25464:5;:11;25244:233;;25559:3;25542:13;;:20;25538:34;;25564:8;;;25538:34;25130:458;;25105:483;24925:681;;;:::o;38264:716::-;38427:4;38473:2;38448:45;;;38494:19;:17;:19::i;:::-;38515:4;38521:7;38530:5;38448:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;38444:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38748:1;38731:6;:13;:18;38727:235;;38777:40;;;;;;;;;;;;;;38727:235;38920:6;38914:13;38905:6;38901:2;38897:15;38890:38;38444:529;38617:54;;;38607:64;;;:6;:64;;;;38600:71;;;38264:716;;;;;;:::o;60324:922::-;60377:7;60397:14;60414:1;60397:18;;60464:6;60455:5;:15;60451:102;;60500:6;60491:15;;;;;;:::i;:::-;;;;;60535:2;60525:12;;;;60451:102;60580:6;60571:5;:15;60567:102;;60616:6;60607:15;;;;;;:::i;:::-;;;;;60651:2;60641:12;;;;60567:102;60696:6;60687:5;:15;60683:102;;60732:6;60723:15;;;;;;:::i;:::-;;;;;60767:2;60757:12;;;;60683:102;60812:5;60803;:14;60799:99;;60847:5;60838:14;;;;;;:::i;:::-;;;;;60881:1;60871:11;;;;60799:99;60925:5;60916;:14;60912:99;;60960:5;60951:14;;;;;;:::i;:::-;;;;;60994:1;60984:11;;;;60912:99;61038:5;61029;:14;61025:99;;61073:5;61064:14;;;;;;:::i;:::-;;;;;61107:1;61097:11;;;;61025:99;61151:5;61142;:14;61138:66;;61187:1;61177:11;;;;61138:66;61232:6;61225:13;;;60324:922;;;:::o;40639:147::-;40776:6;40639:147;;;;;:::o;69342:229::-;69479:12;69511:52;69533:6;69541:4;69547:1;69550:12;69511:21;:52::i;:::-;69504:59;;69342:229;;;;;:::o;85750:190::-;85875:4;85928;85899:25;85912:5;85919:4;85899:12;:25::i;:::-;:33;85892:40;;85750:190;;;;;:::o;25879:1529::-;25944:20;25967:13;;25944:36;;26009:1;25995:16;;:2;:16;;;25991:48;;26020:19;;;;;;;;;;;;;;25991:48;26066:1;26054:8;:13;26050:44;;26076:18;;;;;;;;;;;;;;26050:44;26107:61;26137:1;26141:2;26145:12;26159:8;26107:21;:61::i;:::-;26650:1;9953:2;26621:1;:25;;26620:31;26608:8;:44;26582:18;:22;26601:2;26582:22;;;;;;;;;;;;;;;;:70;;;;;;;;;;;26929:139;26966:2;27020:33;27043:1;27047:2;27051:1;27020:14;:33::i;:::-;26987:30;27008:8;26987:20;:30::i;:::-;:66;26929:18;:139::i;:::-;26895:17;:31;26913:12;26895:31;;;;;;;;;;;:173;;;;27085:15;27103:12;27085:30;;27130:11;27159:8;27144:12;:23;27130:37;;27182:101;27234:9;;;;;;27230:2;27209:35;;27226:1;27209:35;;;;;;;;;;;;27278:3;27268:7;:13;27182:101;;27315:3;27299:13;:19;;;;26356:974;;27340:60;27369:1;27373:2;27377:12;27391:8;27340:20;:60::i;:::-;25933:1475;25879:1529;;:::o;70462:455::-;70632:12;70690:5;70665:21;:30;;70657:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;70750:12;70764:23;70791:6;:11;;70810:5;70817:4;70791:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70749:73;;;;70840:69;70867:6;70875:7;70884:10;70896:12;70840:26;:69::i;:::-;70833:76;;;;70462:455;;;;;;:::o;86617:296::-;86700:7;86720:20;86743:4;86720:27;;86763:9;86758:118;86782:5;:12;86778:1;:16;86758:118;;;86831:33;86841:12;86855:5;86861:1;86855:8;;;;;;;;:::i;:::-;;;;;;;;86831:9;:33::i;:::-;86816:48;;86796:3;;;;;:::i;:::-;;;;86758:118;;;;86893:12;86886:19;;;86617:296;;;;:::o;21402:322::-;21472:14;21703:1;21693:8;21690:15;21665:23;21661:45;21651:55;;21402:322;;;:::o;73035:644::-;73220:12;73249:7;73245:427;;;73298:1;73277:10;:17;:22;73273:290;;73495:18;73506:6;73495:10;:18::i;:::-;73487:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;73273:290;73584:10;73577:17;;;;73245:427;73627:33;73635:10;73647:12;73627:7;:33::i;:::-;73035:644;;;;;;;:::o;93657:149::-;93720:7;93751:1;93747;:5;:51;;93778:20;93793:1;93796;93778:14;:20::i;:::-;93747:51;;;93755:20;93770:1;93773;93755:14;:20::i;:::-;93747:51;93740:58;;93657:149;;;;:::o;66585:326::-;66645:4;66902:1;66880:7;:19;;;:23;66873:30;;66585:326;;;:::o;74221:552::-;74402:1;74382:10;:17;:21;74378:388;;;74614:10;74608:17;74671:15;74658:10;74654:2;74650:19;74643:44;74378:388;74741:12;74734:20;;;;;;;;;;;:::i;:::-;;;;;;;;93814:268;93882:13;93989:1;93983:4;93976:15;94018:1;94012:4;94005:15;94059:4;94053;94043:21;94034:30;;93814:268;;;;:::o;7:169:1:-;91:11;125:6;120:3;113:19;165:4;160:3;156:14;141:29;;7:169;;;;:::o;182:166::-;322:18;318:1;310:6;306:14;299:42;182:166;:::o;354:366::-;496:3;517:67;581:2;576:3;517:67;:::i;:::-;510:74;;593:93;682:3;593:93;:::i;:::-;711:2;706:3;702:12;695:19;;354:366;;;:::o;726:419::-;892:4;930:2;919:9;915:18;907:26;;979:9;973:4;969:20;965:1;954:9;950:17;943:47;1007:131;1133:4;1007:131;:::i;:::-;999:139;;726:419;;;:::o;1151:75::-;1184:6;1217:2;1211:9;1201:19;;1151:75;:::o;1232:117::-;1341:1;1338;1331:12;1355:117;1464:1;1461;1454:12;1478:149;1514:7;1554:66;1547:5;1543:78;1532:89;;1478:149;;;:::o;1633:120::-;1705:23;1722:5;1705:23;:::i;:::-;1698:5;1695:34;1685:62;;1743:1;1740;1733:12;1685:62;1633:120;:::o;1759:137::-;1804:5;1842:6;1829:20;1820:29;;1858:32;1884:5;1858:32;:::i;:::-;1759:137;;;;:::o;1902:327::-;1960:6;2009:2;1997:9;1988:7;1984:23;1980:32;1977:119;;;2015:79;;:::i;:::-;1977:119;2135:1;2160:52;2204:7;2195:6;2184:9;2180:22;2160:52;:::i;:::-;2150:62;;2106:116;1902:327;;;;:::o;2235:90::-;2269:7;2312:5;2305:13;2298:21;2287:32;;2235:90;;;:::o;2331:109::-;2412:21;2427:5;2412:21;:::i;:::-;2407:3;2400:34;2331:109;;:::o;2446:210::-;2533:4;2571:2;2560:9;2556:18;2548:26;;2584:65;2646:1;2635:9;2631:17;2622:6;2584:65;:::i;:::-;2446:210;;;;:::o;2662:126::-;2699:7;2739:42;2732:5;2728:54;2717:65;;2662:126;;;:::o;2794:96::-;2831:7;2860:24;2878:5;2860:24;:::i;:::-;2849:35;;2794:96;;;:::o;2896:122::-;2969:24;2987:5;2969:24;:::i;:::-;2962:5;2959:35;2949:63;;3008:1;3005;2998:12;2949:63;2896:122;:::o;3024:139::-;3070:5;3108:6;3095:20;3086:29;;3124:33;3151:5;3124:33;:::i;:::-;3024:139;;;;:::o;3169:109::-;3205:7;3245:26;3238:5;3234:38;3223:49;;3169:109;;;:::o;3284:120::-;3356:23;3373:5;3356:23;:::i;:::-;3349:5;3346:34;3336:62;;3394:1;3391;3384:12;3336:62;3284:120;:::o;3410:137::-;3455:5;3493:6;3480:20;3471:29;;3509:32;3535:5;3509:32;:::i;:::-;3410:137;;;;:::o;3553:472::-;3620:6;3628;3677:2;3665:9;3656:7;3652:23;3648:32;3645:119;;;3683:79;;:::i;:::-;3645:119;3803:1;3828:53;3873:7;3864:6;3853:9;3849:22;3828:53;:::i;:::-;3818:63;;3774:117;3930:2;3956:52;4000:7;3991:6;3980:9;3976:22;3956:52;:::i;:::-;3946:62;;3901:117;3553:472;;;;;:::o;4031:99::-;4083:6;4117:5;4111:12;4101:22;;4031:99;;;:::o;4136:246::-;4217:1;4227:113;4241:6;4238:1;4235:13;4227:113;;;4326:1;4321:3;4317:11;4311:18;4307:1;4302:3;4298:11;4291:39;4263:2;4260:1;4256:10;4251:15;;4227:113;;;4374:1;4365:6;4360:3;4356:16;4349:27;4198:184;4136:246;;;:::o;4388:102::-;4429:6;4480:2;4476:7;4471:2;4464:5;4460:14;4456:28;4446:38;;4388:102;;;:::o;4496:377::-;4584:3;4612:39;4645:5;4612:39;:::i;:::-;4667:71;4731:6;4726:3;4667:71;:::i;:::-;4660:78;;4747:65;4805:6;4800:3;4793:4;4786:5;4782:16;4747:65;:::i;:::-;4837:29;4859:6;4837:29;:::i;:::-;4832:3;4828:39;4821:46;;4588:285;4496:377;;;;:::o;4879:313::-;4992:4;5030:2;5019:9;5015:18;5007:26;;5079:9;5073:4;5069:20;5065:1;5054:9;5050:17;5043:47;5107:78;5180:4;5171:6;5107:78;:::i;:::-;5099:86;;4879:313;;;;:::o;5198:77::-;5235:7;5264:5;5253:16;;5198:77;;;:::o;5281:122::-;5354:24;5372:5;5354:24;:::i;:::-;5347:5;5344:35;5334:63;;5393:1;5390;5383:12;5334:63;5281:122;:::o;5409:139::-;5455:5;5493:6;5480:20;5471:29;;5509:33;5536:5;5509:33;:::i;:::-;5409:139;;;;:::o;5554:329::-;5613:6;5662:2;5650:9;5641:7;5637:23;5633:32;5630:119;;;5668:79;;:::i;:::-;5630:119;5788:1;5813:53;5858:7;5849:6;5838:9;5834:22;5813:53;:::i;:::-;5803:63;;5759:117;5554:329;;;;:::o;5889:118::-;5976:24;5994:5;5976:24;:::i;:::-;5971:3;5964:37;5889:118;;:::o;6013:222::-;6106:4;6144:2;6133:9;6129:18;6121:26;;6157:71;6225:1;6214:9;6210:17;6201:6;6157:71;:::i;:::-;6013:222;;;;:::o;6241:118::-;6328:24;6346:5;6328:24;:::i;:::-;6323:3;6316:37;6241:118;;:::o;6365:222::-;6458:4;6496:2;6485:9;6481:18;6473:26;;6509:71;6577:1;6566:9;6562:17;6553:6;6509:71;:::i;:::-;6365:222;;;;:::o;6593:474::-;6661:6;6669;6718:2;6706:9;6697:7;6693:23;6689:32;6686:119;;;6724:79;;:::i;:::-;6686:119;6844:1;6869:53;6914:7;6905:6;6894:9;6890:22;6869:53;:::i;:::-;6859:63;;6815:117;6971:2;6997:53;7042:7;7033:6;7022:9;7018:22;6997:53;:::i;:::-;6987:63;;6942:118;6593:474;;;;;:::o;7073:104::-;7118:7;7147:24;7165:5;7147:24;:::i;:::-;7136:35;;7073:104;;;:::o;7183:138::-;7264:32;7290:5;7264:32;:::i;:::-;7257:5;7254:43;7244:71;;7311:1;7308;7301:12;7244:71;7183:138;:::o;7327:155::-;7381:5;7419:6;7406:20;7397:29;;7435:41;7470:5;7435:41;:::i;:::-;7327:155;;;;:::o;7488:345::-;7555:6;7604:2;7592:9;7583:7;7579:23;7575:32;7572:119;;;7610:79;;:::i;:::-;7572:119;7730:1;7755:61;7808:7;7799:6;7788:9;7784:22;7755:61;:::i;:::-;7745:71;;7701:125;7488:345;;;;:::o;7839:619::-;7916:6;7924;7932;7981:2;7969:9;7960:7;7956:23;7952:32;7949:119;;;7987:79;;:::i;:::-;7949:119;8107:1;8132:53;8177:7;8168:6;8157:9;8153:22;8132:53;:::i;:::-;8122:63;;8078:117;8234:2;8260:53;8305:7;8296:6;8285:9;8281:22;8260:53;:::i;:::-;8250:63;;8205:118;8362:2;8388:53;8433:7;8424:6;8413:9;8409:22;8388:53;:::i;:::-;8378:63;;8333:118;7839:619;;;;;:::o;8464:474::-;8532:6;8540;8589:2;8577:9;8568:7;8564:23;8560:32;8557:119;;;8595:79;;:::i;:::-;8557:119;8715:1;8740:53;8785:7;8776:6;8765:9;8761:22;8740:53;:::i;:::-;8730:63;;8686:117;8842:2;8868:53;8913:7;8904:6;8893:9;8889:22;8868:53;:::i;:::-;8858:63;;8813:118;8464:474;;;;;:::o;8944:332::-;9065:4;9103:2;9092:9;9088:18;9080:26;;9116:71;9184:1;9173:9;9169:17;9160:6;9116:71;:::i;:::-;9197:72;9265:2;9254:9;9250:18;9241:6;9197:72;:::i;:::-;8944:332;;;;;:::o;9282:111::-;9334:7;9363:24;9381:5;9363:24;:::i;:::-;9352:35;;9282:111;;;:::o;9399:152::-;9487:39;9520:5;9487:39;:::i;:::-;9480:5;9477:50;9467:78;;9541:1;9538;9531:12;9467:78;9399:152;:::o;9557:169::-;9618:5;9656:6;9643:20;9634:29;;9672:48;9714:5;9672:48;:::i;:::-;9557:169;;;;:::o;9732:504::-;9815:6;9823;9872:2;9860:9;9851:7;9847:23;9843:32;9840:119;;;9878:79;;:::i;:::-;9840:119;9998:1;10023:68;10083:7;10074:6;10063:9;10059:22;10023:68;:::i;:::-;10013:78;;9969:132;10140:2;10166:53;10211:7;10202:6;10191:9;10187:22;10166:53;:::i;:::-;10156:63;;10111:118;9732:504;;;;;:::o;10242:60::-;10270:3;10291:5;10284:12;;10242:60;;;:::o;10308:142::-;10358:9;10391:53;10409:34;10418:24;10436:5;10418:24;:::i;:::-;10409:34;:::i;:::-;10391:53;:::i;:::-;10378:66;;10308:142;;;:::o;10456:126::-;10506:9;10539:37;10570:5;10539:37;:::i;:::-;10526:50;;10456:126;;;:::o;10588:158::-;10670:9;10703:37;10734:5;10703:37;:::i;:::-;10690:50;;10588:158;;;:::o;10752:195::-;10871:69;10934:5;10871:69;:::i;:::-;10866:3;10859:82;10752:195;;:::o;10953:286::-;11078:4;11116:2;11105:9;11101:18;11093:26;;11129:103;11229:1;11218:9;11214:17;11205:6;11129:103;:::i;:::-;10953:286;;;;:::o;11245:117::-;11354:1;11351;11344:12;11368:117;11477:1;11474;11467:12;11491:117;11600:1;11597;11590:12;11631:568;11704:8;11714:6;11764:3;11757:4;11749:6;11745:17;11741:27;11731:122;;11772:79;;:::i;:::-;11731:122;11885:6;11872:20;11862:30;;11915:18;11907:6;11904:30;11901:117;;;11937:79;;:::i;:::-;11901:117;12051:4;12043:6;12039:17;12027:29;;12105:3;12097:4;12089:6;12085:17;12075:8;12071:32;12068:41;12065:128;;;12112:79;;:::i;:::-;12065:128;11631:568;;;;;:::o;12205:849::-;12309:6;12317;12325;12333;12382:2;12370:9;12361:7;12357:23;12353:32;12350:119;;;12388:79;;:::i;:::-;12350:119;12508:1;12533:53;12578:7;12569:6;12558:9;12554:22;12533:53;:::i;:::-;12523:63;;12479:117;12635:2;12661:53;12706:7;12697:6;12686:9;12682:22;12661:53;:::i;:::-;12651:63;;12606:118;12791:2;12780:9;12776:18;12763:32;12822:18;12814:6;12811:30;12808:117;;;12844:79;;:::i;:::-;12808:117;12957:80;13029:7;13020:6;13009:9;13005:22;12957:80;:::i;:::-;12939:98;;;;12734:313;12205:849;;;;;;;:::o;13060:329::-;13119:6;13168:2;13156:9;13147:7;13143:23;13139:32;13136:119;;;13174:79;;:::i;:::-;13136:119;13294:1;13319:53;13364:7;13355:6;13344:9;13340:22;13319:53;:::i;:::-;13309:63;;13265:117;13060:329;;;;:::o;13395:117::-;13504:1;13501;13494:12;13518:180;13566:77;13563:1;13556:88;13663:4;13660:1;13653:15;13687:4;13684:1;13677:15;13704:281;13787:27;13809:4;13787:27;:::i;:::-;13779:6;13775:40;13917:6;13905:10;13902:22;13881:18;13869:10;13866:34;13863:62;13860:88;;;13928:18;;:::i;:::-;13860:88;13968:10;13964:2;13957:22;13747:238;13704:281;;:::o;13991:129::-;14025:6;14052:20;;:::i;:::-;14042:30;;14081:33;14109:4;14101:6;14081:33;:::i;:::-;13991:129;;;:::o;14126:308::-;14188:4;14278:18;14270:6;14267:30;14264:56;;;14300:18;;:::i;:::-;14264:56;14338:29;14360:6;14338:29;:::i;:::-;14330:37;;14422:4;14416;14412:15;14404:23;;14126:308;;;:::o;14440:146::-;14537:6;14532:3;14527;14514:30;14578:1;14569:6;14564:3;14560:16;14553:27;14440:146;;;:::o;14592:425::-;14670:5;14695:66;14711:49;14753:6;14711:49;:::i;:::-;14695:66;:::i;:::-;14686:75;;14784:6;14777:5;14770:21;14822:4;14815:5;14811:16;14860:3;14851:6;14846:3;14842:16;14839:25;14836:112;;;14867:79;;:::i;:::-;14836:112;14957:54;15004:6;14999:3;14994;14957:54;:::i;:::-;14676:341;14592:425;;;;;:::o;15037:340::-;15093:5;15142:3;15135:4;15127:6;15123:17;15119:27;15109:122;;15150:79;;:::i;:::-;15109:122;15267:6;15254:20;15292:79;15367:3;15359:6;15352:4;15344:6;15340:17;15292:79;:::i;:::-;15283:88;;15099:278;15037:340;;;;:::o;15383:509::-;15452:6;15501:2;15489:9;15480:7;15476:23;15472:32;15469:119;;;15507:79;;:::i;:::-;15469:119;15655:1;15644:9;15640:17;15627:31;15685:18;15677:6;15674:30;15671:117;;;15707:79;;:::i;:::-;15671:117;15812:63;15867:7;15858:6;15847:9;15843:22;15812:63;:::i;:::-;15802:73;;15598:287;15383:509;;;;:::o;15898:116::-;15968:21;15983:5;15968:21;:::i;:::-;15961:5;15958:32;15948:60;;16004:1;16001;15994:12;15948:60;15898:116;:::o;16020:133::-;16063:5;16101:6;16088:20;16079:29;;16117:30;16141:5;16117:30;:::i;:::-;16020:133;;;;:::o;16159:468::-;16224:6;16232;16281:2;16269:9;16260:7;16256:23;16252:32;16249:119;;;16287:79;;:::i;:::-;16249:119;16407:1;16432:53;16477:7;16468:6;16457:9;16453:22;16432:53;:::i;:::-;16422:63;;16378:117;16534:2;16560:50;16602:7;16593:6;16582:9;16578:22;16560:50;:::i;:::-;16550:60;;16505:115;16159:468;;;;;:::o;16633:77::-;16670:7;16699:5;16688:16;;16633:77;;;:::o;16716:122::-;16789:24;16807:5;16789:24;:::i;:::-;16782:5;16779:35;16769:63;;16828:1;16825;16818:12;16769:63;16716:122;:::o;16844:139::-;16890:5;16928:6;16915:20;16906:29;;16944:33;16971:5;16944:33;:::i;:::-;16844:139;;;;:::o;16989:329::-;17048:6;17097:2;17085:9;17076:7;17072:23;17068:32;17065:119;;;17103:79;;:::i;:::-;17065:119;17223:1;17248:53;17293:7;17284:6;17273:9;17269:22;17248:53;:::i;:::-;17238:63;;17194:117;16989:329;;;;:::o;17324:307::-;17385:4;17475:18;17467:6;17464:30;17461:56;;;17497:18;;:::i;:::-;17461:56;17535:29;17557:6;17535:29;:::i;:::-;17527:37;;17619:4;17613;17609:15;17601:23;;17324:307;;;:::o;17637:423::-;17714:5;17739:65;17755:48;17796:6;17755:48;:::i;:::-;17739:65;:::i;:::-;17730:74;;17827:6;17820:5;17813:21;17865:4;17858:5;17854:16;17903:3;17894:6;17889:3;17885:16;17882:25;17879:112;;;17910:79;;:::i;:::-;17879:112;18000:54;18047:6;18042:3;18037;18000:54;:::i;:::-;17720:340;17637:423;;;;;:::o;18079:338::-;18134:5;18183:3;18176:4;18168:6;18164:17;18160:27;18150:122;;18191:79;;:::i;:::-;18150:122;18308:6;18295:20;18333:78;18407:3;18399:6;18392:4;18384:6;18380:17;18333:78;:::i;:::-;18324:87;;18140:277;18079:338;;;;:::o;18423:943::-;18518:6;18526;18534;18542;18591:3;18579:9;18570:7;18566:23;18562:33;18559:120;;;18598:79;;:::i;:::-;18559:120;18718:1;18743:53;18788:7;18779:6;18768:9;18764:22;18743:53;:::i;:::-;18733:63;;18689:117;18845:2;18871:53;18916:7;18907:6;18896:9;18892:22;18871:53;:::i;:::-;18861:63;;18816:118;18973:2;18999:53;19044:7;19035:6;19024:9;19020:22;18999:53;:::i;:::-;18989:63;;18944:118;19129:2;19118:9;19114:18;19101:32;19160:18;19152:6;19149:30;19146:117;;;19182:79;;:::i;:::-;19146:117;19287:62;19341:7;19332:6;19321:9;19317:22;19287:62;:::i;:::-;19277:72;;19072:287;18423:943;;;;;;;:::o;19372:180::-;19420:77;19417:1;19410:88;19517:4;19514:1;19507:15;19541:4;19538:1;19531:15;19558:114;19640:1;19633:5;19630:12;19620:46;;19646:18;;:::i;:::-;19620:46;19558:114;:::o;19678:129::-;19724:7;19753:5;19742:16;;19759:42;19795:5;19759:42;:::i;:::-;19678:129;;;:::o;19813:::-;19870:9;19903:33;19930:5;19903:33;:::i;:::-;19890:46;;19813:129;;;:::o;19948:145::-;20042:44;20080:5;20042:44;:::i;:::-;20037:3;20030:57;19948:145;;:::o;20099:236::-;20199:4;20237:2;20226:9;20222:18;20214:26;;20250:78;20325:1;20314:9;20310:17;20301:6;20250:78;:::i;:::-;20099:236;;;;:::o;20341:118::-;20428:24;20446:5;20428:24;:::i;:::-;20423:3;20416:37;20341:118;;:::o;20465:222::-;20558:4;20596:2;20585:9;20581:18;20573:26;;20609:71;20677:1;20666:9;20662:17;20653:6;20609:71;:::i;:::-;20465:222;;;;:::o;20693:359::-;20767:6;20816:2;20804:9;20795:7;20791:23;20787:32;20784:119;;;20822:79;;:::i;:::-;20784:119;20942:1;20967:68;21027:7;21018:6;21007:9;21003:22;20967:68;:::i;:::-;20957:78;;20913:132;20693:359;;;;:::o;21058:474::-;21126:6;21134;21183:2;21171:9;21162:7;21158:23;21154:32;21151:119;;;21189:79;;:::i;:::-;21151:119;21309:1;21334:53;21379:7;21370:6;21359:9;21355:22;21334:53;:::i;:::-;21324:63;;21280:117;21436:2;21462:53;21507:7;21498:6;21487:9;21483:22;21462:53;:::i;:::-;21452:63;;21407:118;21058:474;;;;;:::o;21538:180::-;21586:77;21583:1;21576:88;21683:4;21680:1;21673:15;21707:4;21704:1;21697:15;21724:320;21768:6;21805:1;21799:4;21795:12;21785:22;;21852:1;21846:4;21842:12;21873:18;21863:81;;21929:4;21921:6;21917:17;21907:27;;21863:81;21991:2;21983:6;21980:14;21960:18;21957:38;21954:84;;22010:18;;:::i;:::-;21954:84;21775:269;21724:320;;;:::o;22050:225::-;22190:34;22186:1;22178:6;22174:14;22167:58;22259:8;22254:2;22246:6;22242:15;22235:33;22050:225;:::o;22281:366::-;22423:3;22444:67;22508:2;22503:3;22444:67;:::i;:::-;22437:74;;22520:93;22609:3;22520:93;:::i;:::-;22638:2;22633:3;22629:12;22622:19;;22281:366;;;:::o;22653:419::-;22819:4;22857:2;22846:9;22842:18;22834:26;;22906:9;22900:4;22896:20;22892:1;22881:9;22877:17;22870:47;22934:131;23060:4;22934:131;:::i;:::-;22926:139;;22653:419;;;:::o;23078:230::-;23218:34;23214:1;23206:6;23202:14;23195:58;23287:13;23282:2;23274:6;23270:15;23263:38;23078:230;:::o;23314:366::-;23456:3;23477:67;23541:2;23536:3;23477:67;:::i;:::-;23470:74;;23553:93;23642:3;23553:93;:::i;:::-;23671:2;23666:3;23662:12;23655:19;;23314:366;;;:::o;23686:419::-;23852:4;23890:2;23879:9;23875:18;23867:26;;23939:9;23933:4;23929:20;23925:1;23914:9;23910:17;23903:47;23967:131;24093:4;23967:131;:::i;:::-;23959:139;;23686:419;;;:::o;24111:180::-;24159:77;24156:1;24149:88;24256:4;24253:1;24246:15;24280:4;24277:1;24270:15;24297:191;24337:3;24356:20;24374:1;24356:20;:::i;:::-;24351:25;;24390:20;24408:1;24390:20;:::i;:::-;24385:25;;24433:1;24430;24426:9;24419:16;;24454:3;24451:1;24448:10;24445:36;;;24461:18;;:::i;:::-;24445:36;24297:191;;;;:::o;24494:134::-;24552:9;24585:37;24616:5;24585:37;:::i;:::-;24572:50;;24494:134;;;:::o;24634:147::-;24729:45;24768:5;24729:45;:::i;:::-;24724:3;24717:58;24634:147;;:::o;24787:348::-;24916:4;24954:2;24943:9;24939:18;24931:26;;24967:79;25043:1;25032:9;25028:17;25019:6;24967:79;:::i;:::-;25056:72;25124:2;25113:9;25109:18;25100:6;25056:72;:::i;:::-;24787:348;;;;;:::o;25141:180::-;25281:32;25277:1;25269:6;25265:14;25258:56;25141:180;:::o;25327:366::-;25469:3;25490:67;25554:2;25549:3;25490:67;:::i;:::-;25483:74;;25566:93;25655:3;25566:93;:::i;:::-;25684:2;25679:3;25675:12;25668:19;;25327:366;;;:::o;25699:419::-;25865:4;25903:2;25892:9;25888:18;25880:26;;25952:9;25946:4;25942:20;25938:1;25927:9;25923:17;25916:47;25980:131;26106:4;25980:131;:::i;:::-;25972:139;;25699:419;;;:::o;26124:181::-;26264:33;26260:1;26252:6;26248:14;26241:57;26124:181;:::o;26311:366::-;26453:3;26474:67;26538:2;26533:3;26474:67;:::i;:::-;26467:74;;26550:93;26639:3;26550:93;:::i;:::-;26668:2;26663:3;26659:12;26652:19;;26311:366;;;:::o;26683:419::-;26849:4;26887:2;26876:9;26872:18;26864:26;;26936:9;26930:4;26926:20;26922:1;26911:9;26907:17;26900:47;26964:131;27090:4;26964:131;:::i;:::-;26956:139;;26683:419;;;:::o;27108:165::-;27248:17;27244:1;27236:6;27232:14;27225:41;27108:165;:::o;27279:366::-;27421:3;27442:67;27506:2;27501:3;27442:67;:::i;:::-;27435:74;;27518:93;27607:3;27518:93;:::i;:::-;27636:2;27631:3;27627:12;27620:19;;27279:366;;;:::o;27651:419::-;27817:4;27855:2;27844:9;27840:18;27832:26;;27904:9;27898:4;27894:20;27890:1;27879:9;27875:17;27868:47;27932:131;28058:4;27932:131;:::i;:::-;27924:139;;27651:419;;;:::o;28076:178::-;28216:30;28212:1;28204:6;28200:14;28193:54;28076:178;:::o;28260:366::-;28402:3;28423:67;28487:2;28482:3;28423:67;:::i;:::-;28416:74;;28499:93;28588:3;28499:93;:::i;:::-;28617:2;28612:3;28608:12;28601:19;;28260:366;;;:::o;28632:419::-;28798:4;28836:2;28825:9;28821:18;28813:26;;28885:9;28879:4;28875:20;28871:1;28860:9;28856:17;28849:47;28913:131;29039:4;28913:131;:::i;:::-;28905:139;;28632:419;;;:::o;29057:169::-;29197:21;29193:1;29185:6;29181:14;29174:45;29057:169;:::o;29232:366::-;29374:3;29395:67;29459:2;29454:3;29395:67;:::i;:::-;29388:74;;29471:93;29560:3;29471:93;:::i;:::-;29589:2;29584:3;29580:12;29573:19;;29232:366;;;:::o;29604:419::-;29770:4;29808:2;29797:9;29793:18;29785:26;;29857:9;29851:4;29847:20;29843:1;29832:9;29828:17;29821:47;29885:131;30011:4;29885:131;:::i;:::-;29877:139;;29604:419;;;:::o;30029:410::-;30069:7;30092:20;30110:1;30092:20;:::i;:::-;30087:25;;30126:20;30144:1;30126:20;:::i;:::-;30121:25;;30181:1;30178;30174:9;30203:30;30221:11;30203:30;:::i;:::-;30192:41;;30382:1;30373:7;30369:15;30366:1;30363:22;30343:1;30336:9;30316:83;30293:139;;30412:18;;:::i;:::-;30293:139;30077:362;30029:410;;;;:::o;30445:167::-;30585:19;30581:1;30573:6;30569:14;30562:43;30445:167;:::o;30618:366::-;30760:3;30781:67;30845:2;30840:3;30781:67;:::i;:::-;30774:74;;30857:93;30946:3;30857:93;:::i;:::-;30975:2;30970:3;30966:12;30959:19;;30618:366;;;:::o;30990:419::-;31156:4;31194:2;31183:9;31179:18;31171:26;;31243:9;31237:4;31233:20;31229:1;31218:9;31214:17;31207:47;31271:131;31397:4;31271:131;:::i;:::-;31263:139;;30990:419;;;:::o;31415:233::-;31454:3;31477:24;31495:5;31477:24;:::i;:::-;31468:33;;31523:66;31516:5;31513:77;31510:103;;31593:18;;:::i;:::-;31510:103;31640:1;31633:5;31629:13;31622:20;;31415:233;;;:::o;31654:180::-;31702:77;31699:1;31692:88;31799:4;31796:1;31789:15;31823:4;31820:1;31813:15;31840:141;31889:4;31912:3;31904:11;;31935:3;31932:1;31925:14;31969:4;31966:1;31956:18;31948:26;;31840:141;;;:::o;31987:93::-;32024:6;32071:2;32066;32059:5;32055:14;32051:23;32041:33;;31987:93;;;:::o;32086:107::-;32130:8;32180:5;32174:4;32170:16;32149:37;;32086:107;;;;:::o;32199:393::-;32268:6;32318:1;32306:10;32302:18;32341:97;32371:66;32360:9;32341:97;:::i;:::-;32459:39;32489:8;32478:9;32459:39;:::i;:::-;32447:51;;32531:4;32527:9;32520:5;32516:21;32507:30;;32580:4;32570:8;32566:19;32559:5;32556:30;32546:40;;32275:317;;32199:393;;;;;:::o;32598:142::-;32648:9;32681:53;32699:34;32708:24;32726:5;32708:24;:::i;:::-;32699:34;:::i;:::-;32681:53;:::i;:::-;32668:66;;32598:142;;;:::o;32746:75::-;32789:3;32810:5;32803:12;;32746:75;;;:::o;32827:269::-;32937:39;32968:7;32937:39;:::i;:::-;32998:91;33047:41;33071:16;33047:41;:::i;:::-;33039:6;33032:4;33026:11;32998:91;:::i;:::-;32992:4;32985:105;32903:193;32827:269;;;:::o;33102:73::-;33147:3;33102:73;:::o;33181:189::-;33258:32;;:::i;:::-;33299:65;33357:6;33349;33343:4;33299:65;:::i;:::-;33234:136;33181:189;;:::o;33376:186::-;33436:120;33453:3;33446:5;33443:14;33436:120;;;33507:39;33544:1;33537:5;33507:39;:::i;:::-;33480:1;33473:5;33469:13;33460:22;;33436:120;;;33376:186;;:::o;33568:543::-;33669:2;33664:3;33661:11;33658:446;;;33703:38;33735:5;33703:38;:::i;:::-;33787:29;33805:10;33787:29;:::i;:::-;33777:8;33773:44;33970:2;33958:10;33955:18;33952:49;;;33991:8;33976:23;;33952:49;34014:80;34070:22;34088:3;34070:22;:::i;:::-;34060:8;34056:37;34043:11;34014:80;:::i;:::-;33673:431;;33658:446;33568:543;;;:::o;34117:117::-;34171:8;34221:5;34215:4;34211:16;34190:37;;34117:117;;;;:::o;34240:169::-;34284:6;34317:51;34365:1;34361:6;34353:5;34350:1;34346:13;34317:51;:::i;:::-;34313:56;34398:4;34392;34388:15;34378:25;;34291:118;34240:169;;;;:::o;34414:295::-;34490:4;34636:29;34661:3;34655:4;34636:29;:::i;:::-;34628:37;;34698:3;34695:1;34691:11;34685:4;34682:21;34674:29;;34414:295;;;;:::o;34714:1395::-;34831:37;34864:3;34831:37;:::i;:::-;34933:18;34925:6;34922:30;34919:56;;;34955:18;;:::i;:::-;34919:56;34999:38;35031:4;35025:11;34999:38;:::i;:::-;35084:67;35144:6;35136;35130:4;35084:67;:::i;:::-;35178:1;35202:4;35189:17;;35234:2;35226:6;35223:14;35251:1;35246:618;;;;35908:1;35925:6;35922:77;;;35974:9;35969:3;35965:19;35959:26;35950:35;;35922:77;36025:67;36085:6;36078:5;36025:67;:::i;:::-;36019:4;36012:81;35881:222;35216:887;;35246:618;35298:4;35294:9;35286:6;35282:22;35332:37;35364:4;35332:37;:::i;:::-;35391:1;35405:208;35419:7;35416:1;35413:14;35405:208;;;35498:9;35493:3;35489:19;35483:26;35475:6;35468:42;35549:1;35541:6;35537:14;35527:24;;35596:2;35585:9;35581:18;35568:31;;35442:4;35439:1;35435:12;35430:17;;35405:208;;;35641:6;35632:7;35629:19;35626:179;;;35699:9;35694:3;35690:19;35684:26;35742:48;35784:4;35776:6;35772:17;35761:9;35742:48;:::i;:::-;35734:6;35727:64;35649:156;35626:179;35851:1;35847;35839:6;35835:14;35831:22;35825:4;35818:36;35253:611;;;35216:887;;34806:1303;;;34714:1395;;:::o;36115:180::-;36163:77;36160:1;36153:88;36260:4;36257:1;36250:15;36284:4;36281:1;36274:15;36301:185;36341:1;36358:20;36376:1;36358:20;:::i;:::-;36353:25;;36392:20;36410:1;36392:20;:::i;:::-;36387:25;;36431:1;36421:35;;36436:18;;:::i;:::-;36421:35;36478:1;36475;36471:9;36466:14;;36301:185;;;;:::o;36492:160::-;36632:12;36628:1;36620:6;36616:14;36609:36;36492:160;:::o;36658:366::-;36800:3;36821:67;36885:2;36880:3;36821:67;:::i;:::-;36814:74;;36897:93;36986:3;36897:93;:::i;:::-;37015:2;37010:3;37006:12;36999:19;;36658:366;;;:::o;37030:419::-;37196:4;37234:2;37223:9;37219:18;37211:26;;37283:9;37277:4;37273:20;37269:1;37258:9;37254:17;37247:47;37311:131;37437:4;37311:131;:::i;:::-;37303:139;;37030:419;;;:::o;37455:178::-;37595:30;37591:1;37583:6;37579:14;37572:54;37455:178;:::o;37639:366::-;37781:3;37802:67;37866:2;37861:3;37802:67;:::i;:::-;37795:74;;37878:93;37967:3;37878:93;:::i;:::-;37996:2;37991:3;37987:12;37980:19;;37639:366;;;:::o;38011:419::-;38177:4;38215:2;38204:9;38200:18;38192:26;;38264:9;38258:4;38254:20;38250:1;38239:9;38235:17;38228:47;38292:131;38418:4;38292:131;:::i;:::-;38284:139;;38011:419;;;:::o;38436:143::-;38493:5;38524:6;38518:13;38509:22;;38540:33;38567:5;38540:33;:::i;:::-;38436:143;;;;:::o;38585:351::-;38655:6;38704:2;38692:9;38683:7;38679:23;38675:32;38672:119;;;38710:79;;:::i;:::-;38672:119;38830:1;38855:64;38911:7;38902:6;38891:9;38887:22;38855:64;:::i;:::-;38845:74;;38801:128;38585:351;;;;:::o;38942:173::-;39082:25;39078:1;39070:6;39066:14;39059:49;38942:173;:::o;39121:366::-;39263:3;39284:67;39348:2;39343:3;39284:67;:::i;:::-;39277:74;;39360:93;39449:3;39360:93;:::i;:::-;39478:2;39473:3;39469:12;39462:19;;39121:366;;;:::o;39493:419::-;39659:4;39697:2;39686:9;39682:18;39674:26;;39746:9;39740:4;39736:20;39732:1;39721:9;39717:17;39710:47;39774:131;39900:4;39774:131;:::i;:::-;39766:139;;39493:419;;;:::o;39918:181::-;40058:33;40054:1;40046:6;40042:14;40035:57;39918:181;:::o;40105:366::-;40247:3;40268:67;40332:2;40327:3;40268:67;:::i;:::-;40261:74;;40344:93;40433:3;40344:93;:::i;:::-;40462:2;40457:3;40453:12;40446:19;;40105:366;;;:::o;40477:419::-;40643:4;40681:2;40670:9;40666:18;40658:26;;40730:9;40724:4;40720:20;40716:1;40705:9;40701:17;40694:47;40758:131;40884:4;40758:131;:::i;:::-;40750:139;;40477:419;;;:::o;40902:148::-;41004:11;41041:3;41026:18;;40902:148;;;;:::o;41080:874::-;41183:3;41220:5;41214:12;41249:36;41275:9;41249:36;:::i;:::-;41301:89;41383:6;41378:3;41301:89;:::i;:::-;41294:96;;41421:1;41410:9;41406:17;41437:1;41432:166;;;;41612:1;41607:341;;;;41399:549;;41432:166;41516:4;41512:9;41501;41497:25;41492:3;41485:38;41578:6;41571:14;41564:22;41556:6;41552:35;41547:3;41543:45;41536:52;;41432:166;;41607:341;41674:38;41706:5;41674:38;:::i;:::-;41734:1;41748:154;41762:6;41759:1;41756:13;41748:154;;;41836:7;41830:14;41826:1;41821:3;41817:11;41810:35;41886:1;41877:7;41873:15;41862:26;;41784:4;41781:1;41777:12;41772:17;;41748:154;;;41931:6;41926:3;41922:16;41915:23;;41614:334;;41399:549;;41187:767;;41080:874;;;;:::o;41960:390::-;42066:3;42094:39;42127:5;42094:39;:::i;:::-;42149:89;42231:6;42226:3;42149:89;:::i;:::-;42142:96;;42247:65;42305:6;42300:3;42293:4;42286:5;42282:16;42247:65;:::i;:::-;42337:6;42332:3;42328:16;42321:23;;42070:280;41960:390;;;;:::o;42356:155::-;42496:7;42492:1;42484:6;42480:14;42473:31;42356:155;:::o;42517:400::-;42677:3;42698:84;42780:1;42775:3;42698:84;:::i;:::-;42691:91;;42791:93;42880:3;42791:93;:::i;:::-;42909:1;42904:3;42900:11;42893:18;;42517:400;;;:::o;42923:695::-;43201:3;43223:92;43311:3;43302:6;43223:92;:::i;:::-;43216:99;;43332:95;43423:3;43414:6;43332:95;:::i;:::-;43325:102;;43444:148;43588:3;43444:148;:::i;:::-;43437:155;;43609:3;43602:10;;42923:695;;;;;:::o;43624:168::-;43764:20;43760:1;43752:6;43748:14;43741:44;43624:168;:::o;43798:366::-;43940:3;43961:67;44025:2;44020:3;43961:67;:::i;:::-;43954:74;;44037:93;44126:3;44037:93;:::i;:::-;44155:2;44150:3;44146:12;44139:19;;43798:366;;;:::o;44170:419::-;44336:4;44374:2;44363:9;44359:18;44351:26;;44423:9;44417:4;44413:20;44409:1;44398:9;44394:17;44387:47;44451:131;44577:4;44451:131;:::i;:::-;44443:139;;44170:419;;;:::o;44595:225::-;44735:34;44731:1;44723:6;44719:14;44712:58;44804:8;44799:2;44791:6;44787:15;44780:33;44595:225;:::o;44826:366::-;44968:3;44989:67;45053:2;45048:3;44989:67;:::i;:::-;44982:74;;45065:93;45154:3;45065:93;:::i;:::-;45183:2;45178:3;45174:12;45167:19;;44826:366;;;:::o;45198:419::-;45364:4;45402:2;45391:9;45387:18;45379:26;;45451:9;45445:4;45441:20;45437:1;45426:9;45422:17;45415:47;45479:131;45605:4;45479:131;:::i;:::-;45471:139;;45198:419;;;:::o;45623:182::-;45763:34;45759:1;45751:6;45747:14;45740:58;45623:182;:::o;45811:366::-;45953:3;45974:67;46038:2;46033:3;45974:67;:::i;:::-;45967:74;;46050:93;46139:3;46050:93;:::i;:::-;46168:2;46163:3;46159:12;46152:19;;45811:366;;;:::o;46183:419::-;46349:4;46387:2;46376:9;46372:18;46364:26;;46436:9;46430:4;46426:20;46422:1;46411:9;46407:17;46400:47;46464:131;46590:4;46464:131;:::i;:::-;46456:139;;46183:419;;;:::o;46608:332::-;46729:4;46767:2;46756:9;46752:18;46744:26;;46780:71;46848:1;46837:9;46833:17;46824:6;46780:71;:::i;:::-;46861:72;46929:2;46918:9;46914:18;46905:6;46861:72;:::i;:::-;46608:332;;;;;:::o;46946:137::-;47000:5;47031:6;47025:13;47016:22;;47047:30;47071:5;47047:30;:::i;:::-;46946:137;;;;:::o;47089:345::-;47156:6;47205:2;47193:9;47184:7;47180:23;47176:32;47173:119;;;47211:79;;:::i;:::-;47173:119;47331:1;47356:61;47409:7;47400:6;47389:9;47385:22;47356:61;:::i;:::-;47346:71;;47302:125;47089:345;;;;:::o;47440:179::-;47580:31;47576:1;47568:6;47564:14;47557:55;47440:179;:::o;47625:366::-;47767:3;47788:67;47852:2;47847:3;47788:67;:::i;:::-;47781:74;;47864:93;47953:3;47864:93;:::i;:::-;47982:2;47977:3;47973:12;47966:19;;47625:366;;;:::o;47997:419::-;48163:4;48201:2;48190:9;48186:18;48178:26;;48250:9;48244:4;48240:20;48236:1;48225:9;48221:17;48214:47;48278:131;48404:4;48278:131;:::i;:::-;48270:139;;47997:419;;;:::o;48422:147::-;48523:11;48560:3;48545:18;;48422:147;;;;:::o;48575:114::-;;:::o;48695:398::-;48854:3;48875:83;48956:1;48951:3;48875:83;:::i;:::-;48868:90;;48967:93;49056:3;48967:93;:::i;:::-;49085:1;49080:3;49076:11;49069:18;;48695:398;;;:::o;49099:379::-;49283:3;49305:147;49448:3;49305:147;:::i;:::-;49298:154;;49469:3;49462:10;;49099:379;;;:::o;49484:245::-;49624:34;49620:1;49612:6;49608:14;49601:58;49693:28;49688:2;49680:6;49676:15;49669:53;49484:245;:::o;49735:366::-;49877:3;49898:67;49962:2;49957:3;49898:67;:::i;:::-;49891:74;;49974:93;50063:3;49974:93;:::i;:::-;50092:2;50087:3;50083:12;50076:19;;49735:366;;;:::o;50107:419::-;50273:4;50311:2;50300:9;50296:18;50288:26;;50360:9;50354:4;50350:20;50346:1;50335:9;50331:17;50324:47;50388:131;50514:4;50388:131;:::i;:::-;50380:139;;50107:419;;;:::o;50532:194::-;50572:4;50592:20;50610:1;50592:20;:::i;:::-;50587:25;;50626:20;50644:1;50626:20;:::i;:::-;50621:25;;50670:1;50667;50663:9;50655:17;;50694:1;50688:4;50685:11;50682:37;;;50699:18;;:::i;:::-;50682:37;50532:194;;;;:::o;50732:229::-;50872:34;50868:1;50860:6;50856:14;50849:58;50941:12;50936:2;50928:6;50924:15;50917:37;50732:229;:::o;50967:366::-;51109:3;51130:67;51194:2;51189:3;51130:67;:::i;:::-;51123:74;;51206:93;51295:3;51206:93;:::i;:::-;51324:2;51319:3;51315:12;51308:19;;50967:366;;;:::o;51339:419::-;51505:4;51543:2;51532:9;51528:18;51520:26;;51592:9;51586:4;51582:20;51578:1;51567:9;51563:17;51556:47;51620:131;51746:4;51620:131;:::i;:::-;51612:139;;51339:419;;;:::o;51764:94::-;51797:8;51845:5;51841:2;51837:14;51816:35;;51764:94;;;:::o;51864:::-;51903:7;51932:20;51946:5;51932:20;:::i;:::-;51921:31;;51864:94;;;:::o;51964:100::-;52003:7;52032:26;52052:5;52032:26;:::i;:::-;52021:37;;51964:100;;;:::o;52070:157::-;52175:45;52195:24;52213:5;52195:24;:::i;:::-;52175:45;:::i;:::-;52170:3;52163:58;52070:157;;:::o;52233:256::-;52345:3;52360:75;52431:3;52422:6;52360:75;:::i;:::-;52460:2;52455:3;52451:12;52444:19;;52480:3;52473:10;;52233:256;;;;:::o;52495:98::-;52546:6;52580:5;52574:12;52564:22;;52495:98;;;:::o;52599:168::-;52682:11;52716:6;52711:3;52704:19;52756:4;52751:3;52747:14;52732:29;;52599:168;;;;:::o;52773:373::-;52859:3;52887:38;52919:5;52887:38;:::i;:::-;52941:70;53004:6;52999:3;52941:70;:::i;:::-;52934:77;;53020:65;53078:6;53073:3;53066:4;53059:5;53055:16;53020:65;:::i;:::-;53110:29;53132:6;53110:29;:::i;:::-;53105:3;53101:39;53094:46;;52863:283;52773:373;;;;:::o;53152:640::-;53347:4;53385:3;53374:9;53370:19;53362:27;;53399:71;53467:1;53456:9;53452:17;53443:6;53399:71;:::i;:::-;53480:72;53548:2;53537:9;53533:18;53524:6;53480:72;:::i;:::-;53562;53630:2;53619:9;53615:18;53606:6;53562:72;:::i;:::-;53681:9;53675:4;53671:20;53666:2;53655:9;53651:18;53644:48;53709:76;53780:4;53771:6;53709:76;:::i;:::-;53701:84;;53152:640;;;;;;;:::o;53798:141::-;53854:5;53885:6;53879:13;53870:22;;53901:32;53927:5;53901:32;:::i;:::-;53798:141;;;;:::o;53945:349::-;54014:6;54063:2;54051:9;54042:7;54038:23;54034:32;54031:119;;;54069:79;;:::i;:::-;54031:119;54189:1;54214:63;54269:7;54260:6;54249:9;54245:22;54214:63;:::i;:::-;54204:73;;54160:127;53945:349;;;;:::o;54300:225::-;54440:34;54436:1;54428:6;54424:14;54417:58;54509:8;54504:2;54496:6;54492:15;54485:33;54300:225;:::o;54531:366::-;54673:3;54694:67;54758:2;54753:3;54694:67;:::i;:::-;54687:74;;54770:93;54859:3;54770:93;:::i;:::-;54888:2;54883:3;54879:12;54872:19;;54531:366;;;:::o;54903:419::-;55069:4;55107:2;55096:9;55092:18;55084:26;;55156:9;55150:4;55146:20;55142:1;55131:9;55127:17;55120:47;55184:131;55310:4;55184:131;:::i;:::-;55176:139;;54903:419;;;:::o;55328:386::-;55432:3;55460:38;55492:5;55460:38;:::i;:::-;55514:88;55595:6;55590:3;55514:88;:::i;:::-;55507:95;;55611:65;55669:6;55664:3;55657:4;55650:5;55646:16;55611:65;:::i;:::-;55701:6;55696:3;55692:16;55685:23;;55436:278;55328:386;;;;:::o;55720:271::-;55850:3;55872:93;55961:3;55952:6;55872:93;:::i;:::-;55865:100;;55982:3;55975:10;;55720:271;;;;:::o;55997:179::-;56137:31;56133:1;56125:6;56121:14;56114:55;55997:179;:::o;56182:366::-;56324:3;56345:67;56409:2;56404:3;56345:67;:::i;:::-;56338:74;;56421:93;56510:3;56421:93;:::i;:::-;56539:2;56534:3;56530:12;56523:19;;56182:366;;;:::o;56554:419::-;56720:4;56758:2;56747:9;56743:18;56735:26;;56807:9;56801:4;56797:20;56793:1;56782:9;56778:17;56771:47;56835:131;56961:4;56835:131;:::i;:::-;56827:139;;56554:419;;;:::o

Swarm Source

ipfs://407d7ffd3c55490253a534f3b92cb9204f804d64bd474ea7b48161e4c0fcd091

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

OVERVIEW

In the neon-lit streets of Tokyo, a young woman named Saki is on a mission to become the ultimate drift queen. She is a skilled driver and a huge fan of the retro JDM sportscars of the 90s, heavily inspired by anime. Saki has put all her savings into buying a 1995 Toyota Supra...

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.