ETH Price: $3,475.88 (-1.19%)
Gas: 5 Gwei

Token

WayToku (WTOKU)
 

Overview

Max Total Supply

1,234 WTOKU

Holders

512

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
2 WTOKU
0x745783c8be71f6028d1f798671a221517ea28499
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
WayToku

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-01-14
*/

// File: erc721a/contracts/IERC721A.sol


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

pragma solidity ^0.8.4;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: erc721a/contracts/ERC721A.sol


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

pragma solidity ^0.8.4;


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        return _tokenApprovals[tokenId].value;
    }

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfers(from, to, tokenId, 1);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        address from = address(uint160(prevOwnershipPacked));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;

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

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

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


// OpenZeppelin Contracts (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: @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/security/ReentrancyGuard.sol


// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

// File: contracts/main.sol









pragma solidity ^0.8.17;

contract WayToku is ERC721A, Ownable, ReentrancyGuard {

  using Strings for uint256;

// ================== Variables Start =======================
  
  bytes32 public merkleRoot;
  
  string internal uri;
  string public uriExtenstion = ".json";

  string public hiddenMetadataUri = "https://bafybeigax3syxbmmlv4kcthd3abvch5uqlzb2sda2ex4hog67qvfk35wwi.ipfs.nftstorage.link/reveal.json";

  uint256 public price = 0.007 ether;
  uint256 public wlprice = 0.005 ether;

  uint256 public supplyLimit = 1234;
  uint256 public wlsupplyLimit = 1234;

  uint256 public maxMintAmountPerTx = 2;
  uint256 public wlmaxMintAmountPerTx = 2;

  uint256 public maxLimitPerWallet = 2;
  uint256 public wlmaxLimitPerWallet = 2;

  bool public whitelistSale = false;
  bool public publicSale = false;

  bool public revealed = false;

  bool public burnToggle = false;

  mapping(address => uint256) public wlMintCount;
  mapping(address => uint256) public publicMintCount;
  mapping(uint256  => address) public tokenIDBurnedByAddress;
  mapping(address => uint256) public amountOfTokensBurnedByAddress;

  uint256 public publicMinted;
  uint256 public wlMinted;    
  uint256 public tokensBurned;

// ================== Variables End =======================  

// ================== Constructor Start =======================

  constructor(
    string memory _uri
  ) ERC721A("WayToku", "WTOKU")  {
    seturi(_uri);
  }

// ================== Constructor End =======================

// ================== Mint Functions Start =======================

  function WLmint(uint256 _mintAmount, bytes32[] calldata _merkleProof) public payable {

    // Verify wl requirements
    require(whitelistSale, 'The WlSale is paused!');
    bytes32 leaf = keccak256(abi.encodePacked(_msgSender()));
    require(MerkleProof.verify(_merkleProof, merkleRoot, leaf), 'Invalid proof!');


    // Normal requirements 
    require(_mintAmount > 0 && _mintAmount <= wlmaxMintAmountPerTx, 'Invalid mint amount!');
    require(totalSupply() + _mintAmount <= wlsupplyLimit, 'Max supply exceeded!');
    require(wlMintCount[msg.sender] + _mintAmount <= wlmaxLimitPerWallet, 'Max mint per wallet exceeded!');
    require(msg.value >= wlprice * _mintAmount, 'Insufficient funds!');
     
    // Mint
     _safeMint(_msgSender(), _mintAmount);

    // Mapping update 
    wlMintCount[msg.sender] += _mintAmount; 
    wlMinted += _mintAmount;
  }

  function PublicMint(uint256 _mintAmount) public payable {
    
    // Normal requirements 
    require(publicSale, 'The PublicSale is paused!');
    require(_mintAmount > 0 && _mintAmount <= maxMintAmountPerTx, 'Invalid mint amount!');
    require(totalSupply() + _mintAmount <= supplyLimit, 'Max supply exceeded!');
    require(publicMintCount[msg.sender] + _mintAmount <= maxLimitPerWallet, 'Max mint per wallet exceeded!');
    require(msg.value >= price * _mintAmount, 'Insufficient funds!');
     
    // Mint
     _safeMint(_msgSender(), _mintAmount);

    // Mapping update 
    publicMintCount[msg.sender] += _mintAmount;  
    publicMinted += _mintAmount;   
  }  

  function OwnerMint(uint256 _mintAmount, address _receiver) public onlyOwner {
    require(totalSupply() + _mintAmount <= supplyLimit, 'Max supply exceeded!');
    _safeMint(_receiver, _mintAmount);
  }

    function MassAirdrop(address[] calldata receivers) public onlyOwner {
    for (uint256 i; i < receivers.length; ++i) {
      require(totalSupply() + 20 <= supplyLimit, 'Max supply exceeded!');
      _mint(receivers[i], 20);
    }
  }
  

// ================== Mint Functions End =======================  

// ================== Burn Functions Start ======================= 

 function Burn(uint256 _tokenID) public{
   require(burnToggle, "Burn phase not started yet");
   require(_msgSender() == ownerOf(_tokenID), "Not the owner!");

   _burn(_tokenID);
   tokenIDBurnedByAddress[_tokenID] = _msgSender();
   amountOfTokensBurnedByAddress[_msgSender()] += 1;
   tokensBurned +=1;
 }
// ================== Burn Functions End ======================= 


// ================== Set Functions Start =======================

// reveal
  function setRevealed(bool _state) public onlyOwner {
    revealed = _state;
  }

// uri
  function seturi(string memory _uri) public onlyOwner {
    uri = _uri;
  }

  function seturiExtenstion(string memory _uriExtenstion) public onlyOwner {
    uriExtenstion = _uriExtenstion;
  }

  function setHiddenMetadataUri(string memory _hiddenMetadataUri) public onlyOwner {
    hiddenMetadataUri = _hiddenMetadataUri;
  }

// sales toggle
  function setpublicSale(bool _publicSale) public onlyOwner {
    publicSale = _publicSale;
  }

  function setwlSale(bool _whitelistSale) public onlyOwner {
    whitelistSale = _whitelistSale;
  }

// hash set
  function setwlMerkleRootHash(bytes32 _merkleRoot) public onlyOwner {
    merkleRoot = _merkleRoot;
  }

// max per tx
  function setMaxMintAmountPerTx(uint256 _maxMintAmountPerTx) public onlyOwner {
    maxMintAmountPerTx = _maxMintAmountPerTx;
  }

  function setwlmaxMintAmountPerTx(uint256 _wlmaxMintAmountPerTx) public onlyOwner {
    wlmaxMintAmountPerTx = _wlmaxMintAmountPerTx;
  }

// pax per wallet
  function setmaxLimitPerWallet(uint256 _maxLimitPerWallet) public onlyOwner {
    maxLimitPerWallet = _maxLimitPerWallet;
  }

  function setwlmaxLimitPerWallet(uint256 _wlmaxLimitPerWallet) public onlyOwner {
    wlmaxLimitPerWallet = _wlmaxLimitPerWallet;
  }  

// price
  function setPrice(uint256 _price) public onlyOwner {
    price = _price;
  }

  function setwlPrice(uint256 _wlprice) public onlyOwner {
    wlprice = _wlprice;
  }  

// supply limit
  function setsupplyLimit(uint256 _supplyLimit) public onlyOwner {
    supplyLimit = _supplyLimit;
  }

  function setwlsupplyLimit(uint256 _wlsupplyLimit) public onlyOwner {
    wlsupplyLimit = _wlsupplyLimit;
  }  

// burn toggle
  function setburnToggle(bool _state) public onlyOwner{
    burnToggle = _state;
  }  

// ================== Set Functions End =======================

// ================== Withdraw Function Start =======================
  
  function withdraw() public onlyOwner nonReentrant {
    //owner withdraw
    (bool os, ) = payable(owner()).call{value: address(this).balance}('');
    require(os);
  }

// ================== Withdraw Function End=======================  

// ================== Read Functions Start =======================

  function tokensOfOwner(address owner) external view returns (uint256[] memory) {
    unchecked {
        uint256[] memory a = new uint256[](balanceOf(owner)); 
        uint256 end = _nextTokenId();
        uint256 tokenIdsIdx;
        address currOwnershipAddr;
        for (uint256 i; i < end; i++) {
            TokenOwnership memory ownership = _ownershipAt(i);
            if (ownership.burned) {
                continue;
            }
            if (ownership.addr != address(0)) {
                currOwnershipAddr = ownership.addr;
            }
            if (currOwnershipAddr == owner) {
                a[tokenIdsIdx++] = i;
            }
        }
        return a;    
    }
}

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

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

    if (revealed == false) {
      return hiddenMetadataUri;
    }

    string memory currentBaseURI = _baseURI();
    return bytes(currentBaseURI).length > 0
        ? string(abi.encodePacked(currentBaseURI, _tokenId.toString(), uriExtenstion))
        : '';
  }

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"uint256","name":"_tokenID","type":"uint256"}],"name":"Burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"receivers","type":"address[]"}],"name":"MassAirdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"OwnerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"PublicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"WLmint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"amountOfTokensBurnedByAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnToggle","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hiddenMetadataUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxLimitPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintAmountPerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"publicMintCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_hiddenMetadataUri","type":"string"}],"name":"setHiddenMetadataUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxMintAmountPerTx","type":"uint256"}],"name":"setMaxMintAmountPerTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setburnToggle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxLimitPerWallet","type":"uint256"}],"name":"setmaxLimitPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_publicSale","type":"bool"}],"name":"setpublicSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supplyLimit","type":"uint256"}],"name":"setsupplyLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"seturi","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriExtenstion","type":"string"}],"name":"seturiExtenstion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setwlMerkleRootHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_wlprice","type":"uint256"}],"name":"setwlPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_whitelistSale","type":"bool"}],"name":"setwlSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_wlmaxLimitPerWallet","type":"uint256"}],"name":"setwlmaxLimitPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_wlmaxMintAmountPerTx","type":"uint256"}],"name":"setwlmaxMintAmountPerTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_wlsupplyLimit","type":"uint256"}],"name":"setwlsupplyLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supplyLimit","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":"","type":"uint256"}],"name":"tokenIDBurnedByAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uriExtenstion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistSale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wlMintCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wlMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wlmaxLimitPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wlmaxMintAmountPerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wlprice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wlsupplyLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60806040526040518060400160405280600581526020017f2e6a736f6e000000000000000000000000000000000000000000000000000000815250600c90816200004a919062000664565b506040518060a00160405280606481526020016200566660649139600d908162000075919062000664565b506618de76816d8000600e556611c37937e08000600f556104d26010556104d260115560026012556002601355600260145560026015556000601660006101000a81548160ff0219169083151502179055506000601660016101000a81548160ff0219169083151502179055506000601660026101000a81548160ff0219169083151502179055506000601660036101000a81548160ff0219169083151502179055503480156200012557600080fd5b50604051620056ca380380620056ca83398181016040528101906200014b9190620008af565b6040518060400160405280600781526020017f576179546f6b75000000000000000000000000000000000000000000000000008152506040518060400160405280600581526020017f57544f4b550000000000000000000000000000000000000000000000000000008152508160029081620001c8919062000664565b508060039081620001da919062000664565b50620001eb6200023360201b60201c565b600081905550505062000213620002076200023c60201b60201c565b6200024460201b60201c565b60016009819055506200022c816200030a60201b60201c565b5062000983565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6200031a6200032f60201b60201c565b80600b90816200032b919062000664565b5050565b6200033f6200023c60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1662000365620003c060201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1614620003be576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003b59062000961565b60405180910390fd5b565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200046c57607f821691505b60208210810362000482576200048162000424565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620004ec7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620004ad565b620004f88683620004ad565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620005456200053f620005398462000510565b6200051a565b62000510565b9050919050565b6000819050919050565b620005618362000524565b6200057962000570826200054c565b848454620004ba565b825550505050565b600090565b6200059062000581565b6200059d81848462000556565b505050565b5b81811015620005c557620005b960008262000586565b600181019050620005a3565b5050565b601f8211156200061457620005de8162000488565b620005e9846200049d565b81016020851015620005f9578190505b6200061162000608856200049d565b830182620005a2565b50505b505050565b600082821c905092915050565b6000620006396000198460080262000619565b1980831691505092915050565b600062000654838362000626565b9150826002028217905092915050565b6200066f82620003ea565b67ffffffffffffffff8111156200068b576200068a620003f5565b5b62000697825462000453565b620006a4828285620005c9565b600060209050601f831160018114620006dc5760008415620006c7578287015190505b620006d3858262000646565b86555062000743565b601f198416620006ec8662000488565b60005b828110156200071657848901518255600182019150602085019450602081019050620006ef565b8683101562000736578489015162000732601f89168262000626565b8355505b6001600288020188555050505b505050505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b620007858262000769565b810181811067ffffffffffffffff82111715620007a757620007a6620003f5565b5b80604052505050565b6000620007bc6200074b565b9050620007ca82826200077a565b919050565b600067ffffffffffffffff821115620007ed57620007ec620003f5565b5b620007f88262000769565b9050602081019050919050565b60005b838110156200082557808201518184015260208101905062000808565b60008484015250505050565b6000620008486200084284620007cf565b620007b0565b90508281526020810184848401111562000867576200086662000764565b5b6200087484828562000805565b509392505050565b600082601f8301126200089457620008936200075f565b5b8151620008a684826020860162000831565b91505092915050565b600060208284031215620008c857620008c762000755565b5b600082015167ffffffffffffffff811115620008e957620008e86200075a565b5b620008f7848285016200087c565b91505092915050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006200094960208362000900565b9150620009568262000911565b602082019050919050565b600060208201905081810360008301526200097c816200093a565b9050919050565b614cd380620009936000396000f3fe6080604052600436106103ac5760003560e01c8063869194ac116101e7578063b071401b1161010d578063e41f4673116100a0578063ee8b4ac61161006f578063ee8b4ac614610d8d578063f2cd579614610db8578063f2fde38b14610de3578063f648498014610e0c576103ac565b8063e41f467314610cbf578063e7873b5814610ce8578063e78b355314610d13578063e985e9c514610d50576103ac565b8063d9f0a671116100dc578063d9f0a67114610c19578063dc544ca714610c42578063e0a8085314610c6d578063e35b0ab114610c96576103ac565b8063b071401b14610b6e578063b88d4fde14610b97578063b90306ad14610bb3578063c87b56dd14610bdc576103ac565b80639cb257d011610185578063a28b56f211610154578063a28b56f214610ac6578063a45ba8e714610aef578063a4f4f8af14610b1a578063abe37a9414610b45576103ac565b80639cb257d014610a2d5780639fb17e3414610a56578063a035b1fe14610a72578063a22cb46514610a9d576103ac565b806393c7efbb116101c157806393c7efbb1461097e57806394354fd01461099a57806395d89b41146109c557806396330b5f146109f0576103ac565b8063869194ac146108ff5780638da5cb5b1461092a57806391b7f5ed14610955576103ac565b80633ccfd60b116102d75780635a0b8b231161026a57806370cad3aa1161023957806370cad3aa14610843578063715018a61461088057806378d45eef146108975780638462151c146108c2576103ac565b80635a0b8b23146107755780635c22abd2146107a05780636352211e146107c957806370a0823114610806576103ac565b806347d9569e116102a657806347d9569e146106bb57806349a79dd3146106e45780634fdd43cb14610721578063518302271461074a576103ac565b80633ccfd60b1461063457806342842e0e1461064b578063454bb2a814610667578063463fb32314610690576103ac565b806318160ddd1161034f5780632eb4a7ab1161031e5780632eb4a7ab1461058a5780632eba0dce146105b557806331ffd6f1146105de57806333bc1c5c14610609576103ac565b806318160ddd146104ef57806319d1997a1461051a57806323b872dd14610545578063287e4a7014610561576103ac565b806306fdde031161038b57806306fdde0314610442578063081812fc1461046d578063095ea7b3146104aa5780630e13a7c0146104c6576103ac565b806275770a146103b157806301ffc9a7146103da5780630284b5f414610417575b600080fd5b3480156103bd57600080fd5b506103d860048036038101906103d39190613699565b610e35565b005b3480156103e657600080fd5b5061040160048036038101906103fc919061371e565b610e47565b60405161040e9190613766565b60405180910390f35b34801561042357600080fd5b5061042c610ed9565b6040516104399190613811565b60405180910390f35b34801561044e57600080fd5b50610457610f67565b6040516104649190613811565b60405180910390f35b34801561047957600080fd5b50610494600480360381019061048f9190613699565b610ff9565b6040516104a19190613874565b60405180910390f35b6104c460048036038101906104bf91906138bb565b611078565b005b3480156104d257600080fd5b506104ed60048036038101906104e89190613699565b6111bc565b005b3480156104fb57600080fd5b506105046111ce565b604051610511919061390a565b60405180910390f35b34801561052657600080fd5b5061052f6111e5565b60405161053c919061390a565b60405180910390f35b61055f600480360381019061055a9190613925565b6111eb565b005b34801561056d57600080fd5b50610588600480360381019061058391906139a4565b61150d565b005b34801561059657600080fd5b5061059f611532565b6040516105ac91906139ea565b60405180910390f35b3480156105c157600080fd5b506105dc60048036038101906105d79190613a05565b611538565b005b3480156105ea57600080fd5b506105f36115a5565b6040516106009190613766565b60405180910390f35b34801561061557600080fd5b5061061e6115b8565b60405161062b9190613766565b60405180910390f35b34801561064057600080fd5b506106496115cb565b005b61066560048036038101906106609190613925565b611663565b005b34801561067357600080fd5b5061068e60048036038101906106899190613699565b611683565b005b34801561069c57600080fd5b506106a5611695565b6040516106b2919061390a565b60405180910390f35b3480156106c757600080fd5b506106e260048036038101906106dd9190613aaa565b61169b565b005b3480156106f057600080fd5b5061070b60048036038101906107069190613af7565b611751565b604051610718919061390a565b60405180910390f35b34801561072d57600080fd5b5061074860048036038101906107439190613c54565b611769565b005b34801561075657600080fd5b5061075f611784565b60405161076c9190613766565b60405180910390f35b34801561078157600080fd5b5061078a611797565b604051610797919061390a565b60405180910390f35b3480156107ac57600080fd5b506107c760048036038101906107c291906139a4565b61179d565b005b3480156107d557600080fd5b506107f060048036038101906107eb9190613699565b6117c2565b6040516107fd9190613874565b60405180910390f35b34801561081257600080fd5b5061082d60048036038101906108289190613af7565b6117d4565b60405161083a919061390a565b60405180910390f35b34801561084f57600080fd5b5061086a60048036038101906108659190613af7565b61188c565b604051610877919061390a565b60405180910390f35b34801561088c57600080fd5b506108956118a4565b005b3480156108a357600080fd5b506108ac6118b8565b6040516108b9919061390a565b60405180910390f35b3480156108ce57600080fd5b506108e960048036038101906108e49190613af7565b6118be565b6040516108f69190613d5b565b60405180910390f35b34801561090b57600080fd5b50610914611a02565b604051610921919061390a565b60405180910390f35b34801561093657600080fd5b5061093f611a08565b60405161094c9190613874565b60405180910390f35b34801561096157600080fd5b5061097c60048036038101906109779190613699565b611a32565b005b61099860048036038101906109939190613dd3565b611a44565b005b3480156109a657600080fd5b506109af611d5f565b6040516109bc919061390a565b60405180910390f35b3480156109d157600080fd5b506109da611d65565b6040516109e79190613811565b60405180910390f35b3480156109fc57600080fd5b50610a176004803603810190610a129190613af7565b611df7565b604051610a24919061390a565b60405180910390f35b348015610a3957600080fd5b50610a546004803603810190610a4f91906139a4565b611e0f565b005b610a706004803603810190610a6b9190613699565b611e34565b005b348015610a7e57600080fd5b50610a8761208d565b604051610a94919061390a565b60405180910390f35b348015610aa957600080fd5b50610ac46004803603810190610abf9190613e33565b612093565b005b348015610ad257600080fd5b50610aed6004803603810190610ae89190613e9f565b61219e565b005b348015610afb57600080fd5b50610b046121b0565b604051610b119190613811565b60405180910390f35b348015610b2657600080fd5b50610b2f61223e565b604051610b3c919061390a565b60405180910390f35b348015610b5157600080fd5b50610b6c6004803603810190610b679190613699565b612244565b005b348015610b7a57600080fd5b50610b956004803603810190610b909190613699565b612256565b005b610bb16004803603810190610bac9190613f6d565b612268565b005b348015610bbf57600080fd5b50610bda6004803603810190610bd59190613699565b6122db565b005b348015610be857600080fd5b50610c036004803603810190610bfe9190613699565b612484565b604051610c109190613811565b60405180910390f35b348015610c2557600080fd5b50610c406004803603810190610c3b9190613699565b6125dc565b005b348015610c4e57600080fd5b50610c576125ee565b604051610c64919061390a565b60405180910390f35b348015610c7957600080fd5b50610c946004803603810190610c8f91906139a4565b6125f4565b005b348015610ca257600080fd5b50610cbd6004803603810190610cb89190613699565b612619565b005b348015610ccb57600080fd5b50610ce66004803603810190610ce19190613c54565b61262b565b005b348015610cf457600080fd5b50610cfd612646565b604051610d0a919061390a565b60405180910390f35b348015610d1f57600080fd5b50610d3a6004803603810190610d359190613699565b61264c565b604051610d479190613874565b60405180910390f35b348015610d5c57600080fd5b50610d776004803603810190610d729190613ff0565b61267f565b604051610d849190613766565b60405180910390f35b348015610d9957600080fd5b50610da2612713565b604051610daf9190613766565b60405180910390f35b348015610dc457600080fd5b50610dcd612726565b604051610dda919061390a565b60405180910390f35b348015610def57600080fd5b50610e0a6004803603810190610e059190613af7565b61272c565b005b348015610e1857600080fd5b50610e336004803603810190610e2e9190613c54565b6127af565b005b610e3d6127ca565b8060108190555050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610ea257506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610ed25750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600c8054610ee69061405f565b80601f0160208091040260200160405190810160405280929190818152602001828054610f129061405f565b8015610f5f5780601f10610f3457610100808354040283529160200191610f5f565b820191906000526020600020905b815481529060010190602001808311610f4257829003601f168201915b505050505081565b606060028054610f769061405f565b80601f0160208091040260200160405190810160405280929190818152602001828054610fa29061405f565b8015610fef5780601f10610fc457610100808354040283529160200191610fef565b820191906000526020600020905b815481529060010190602001808311610fd257829003601f168201915b5050505050905090565b600061100482612848565b61103a576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000611083826117c2565b90508073ffffffffffffffffffffffffffffffffffffffff166110a46128a7565b73ffffffffffffffffffffffffffffffffffffffff1614611107576110d0816110cb6128a7565b61267f565b611106576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6111c46127ca565b80600f8190555050565b60006111d86128af565b6001546000540303905090565b60105481565b60006111f6826128b8565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461125d576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061126984612984565b9150915061127f818761127a6128a7565b6129ab565b6112cb576112948661128f6128a7565b61267f565b6112ca576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611331576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61133e86868660016129ef565b801561134957600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550611417856113f38888876129f5565b7c020000000000000000000000000000000000000000000000000000000017612a1d565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361149d576000600185019050600060046000838152602001908152602001600020540361149b57600054811461149a578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46115058686866001612a48565b505050505050565b6115156127ca565b80601660036101000a81548160ff02191690831515021790555050565b600a5481565b6115406127ca565b6010548261154c6111ce565b61155691906140bf565b1115611597576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158e9061413f565b60405180910390fd5b6115a18183612a4e565b5050565b601660009054906101000a900460ff1681565b601660019054906101000a900460ff1681565b6115d36127ca565b6115db612a6c565b60006115e5611a08565b73ffffffffffffffffffffffffffffffffffffffff164760405161160890614190565b60006040518083038185875af1925050503d8060008114611645576040519150601f19603f3d011682016040523d82523d6000602084013e61164a565b606091505b505090508061165857600080fd5b50611661612abb565b565b61167e83838360405180602001604052806000815250612268565b505050565b61168b6127ca565b8060158190555050565b601c5481565b6116a36127ca565b60005b8282905081101561174c5760105460146116be6111ce565b6116c891906140bf565b1115611709576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117009061413f565b60405180910390fd5b61173b83838381811061171f5761171e6141a5565b5b90506020020160208101906117349190613af7565b6014612ac5565b80611745906141d4565b90506116a6565b505050565b601a6020528060005260406000206000915090505481565b6117716127ca565b80600d908161178091906143c8565b5050565b601660029054906101000a900460ff1681565b60145481565b6117a56127ca565b80601660016101000a81548160ff02191690831515021790555050565b60006117cd826128b8565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361183b576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b60176020528060005260406000206000915090505481565b6118ac6127ca565b6118b66000612c80565b565b60115481565b606060006118cb836117d4565b67ffffffffffffffff8111156118e4576118e3613b29565b5b6040519080825280602002602001820160405280156119125781602001602082028036833780820191505090505b509050600061191f612d46565b905060008060005b838110156119f557600061193a82612d4f565b905080604001511561194c57506119e8565b600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161461198c57806000015192505b8773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036119e657818685806001019650815181106119d9576119d86141a5565b5b6020026020010181815250505b505b8080600101915050611927565b5083945050505050919050565b60155481565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611a3a6127ca565b80600e8190555050565b601660009054906101000a900460ff16611a93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8a906144e6565b60405180910390fd5b6000611a9d612d7a565b604051602001611aad919061454e565b604051602081830303815290604052805190602001209050611b13838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600a5483612d82565b611b52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b49906145b5565b60405180910390fd5b600084118015611b6457506013548411155b611ba3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9a90614621565b60405180910390fd5b60115484611baf6111ce565b611bb991906140bf565b1115611bfa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf19061413f565b60405180910390fd5b60155484601760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c4891906140bf565b1115611c89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c809061468d565b60405180910390fd5b83600f54611c9791906146ad565b341015611cd9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd09061473b565b60405180910390fd5b611cea611ce4612d7a565b85612a4e565b83601760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d3991906140bf565b9250508190555083601c6000828254611d5291906140bf565b9250508190555050505050565b60125481565b606060038054611d749061405f565b80601f0160208091040260200160405190810160405280929190818152602001828054611da09061405f565b8015611ded5780601f10611dc257610100808354040283529160200191611ded565b820191906000526020600020905b815481529060010190602001808311611dd057829003601f168201915b5050505050905090565b60186020528060005260406000206000915090505481565b611e176127ca565b80601660006101000a81548160ff02191690831515021790555050565b601660019054906101000a900460ff16611e83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e7a906147a7565b60405180910390fd5b600081118015611e9557506012548111155b611ed4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ecb90614621565b60405180910390fd5b60105481611ee06111ce565b611eea91906140bf565b1115611f2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f229061413f565b60405180910390fd5b60145481601860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611f7991906140bf565b1115611fba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb19061468d565b60405180910390fd5b80600e54611fc891906146ad565b34101561200a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120019061473b565b60405180910390fd5b61201b612015612d7a565b82612a4e565b80601860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461206a91906140bf565b9250508190555080601b600082825461208391906140bf565b9250508190555050565b600e5481565b80600760006120a06128a7565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661214d6128a7565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516121929190613766565b60405180910390a35050565b6121a66127ca565b80600a8190555050565b600d80546121bd9061405f565b80601f01602080910402602001604051908101604052809291908181526020018280546121e99061405f565b80156122365780601f1061220b57610100808354040283529160200191612236565b820191906000526020600020905b81548152906001019060200180831161221957829003601f168201915b505050505081565b601b5481565b61224c6127ca565b8060138190555050565b61225e6127ca565b8060128190555050565b6122738484846111eb565b60008373ffffffffffffffffffffffffffffffffffffffff163b146122d55761229e84848484612d99565b6122d4576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b601660039054906101000a900460ff1661232a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161232190614813565b60405180910390fd5b612333816117c2565b73ffffffffffffffffffffffffffffffffffffffff16612351612d7a565b73ffffffffffffffffffffffffffffffffffffffff16146123a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161239e9061487f565b60405180910390fd5b6123b081612ee9565b6123b8612d7a565b6019600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001601a6000612417612d7a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461246091906140bf565b925050819055506001601d600082825461247a91906140bf565b9250508190555050565b606061248f82612848565b6124ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124c590614911565b60405180910390fd5b60001515601660029054906101000a900460ff1615150361257b57600d80546124f69061405f565b80601f01602080910402602001604051908101604052809291908181526020018280546125229061405f565b801561256f5780601f106125445761010080835404028352916020019161256f565b820191906000526020600020905b81548152906001019060200180831161255257829003601f168201915b505050505090506125d7565b6000612585612ef7565b905060008151116125a557604051806020016040528060008152506125d3565b806125af84612f89565b600c6040516020016125c3939291906149f0565b6040516020818303038152906040525b9150505b919050565b6125e46127ca565b8060148190555050565b600f5481565b6125fc6127ca565b80601660026101000a81548160ff02191690831515021790555050565b6126216127ca565b8060118190555050565b6126336127ca565b80600c908161264291906143c8565b5050565b601d5481565b60196020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b601660039054906101000a900460ff1681565b60135481565b6127346127ca565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036127a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279a90614a93565b60405180910390fd5b6127ac81612c80565b50565b6127b76127ca565b80600b90816127c691906143c8565b5050565b6127d2612d7a565b73ffffffffffffffffffffffffffffffffffffffff166127f0611a08565b73ffffffffffffffffffffffffffffffffffffffff1614612846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161283d90614aff565b60405180910390fd5b565b6000816128536128af565b11158015612862575060005482105b80156128a0575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b600080829050806128c76128af565b1161294d5760005481101561294c5760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082160361294a575b60008103612940576004600083600190039350838152602001908152602001600020549050612916565b809250505061297f565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8612a0c868684613057565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b612a68828260405180602001604052806000815250613060565b5050565b600260095403612ab1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612aa890614b6b565b60405180910390fd5b6002600981905550565b6001600981905550565b60008054905060008203612b05576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b1260008483856129ef565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612b8983612b7a60008660006129f5565b612b83856130fd565b17612a1d565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612c2a57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612bef565b5060008203612c65576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050612c7b6000848385612a48565b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008054905090565b612d57613600565b612d73600460008481526020019081526020016000205461310d565b9050919050565b600033905090565b600082612d8f85846131c3565b1490509392505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612dbf6128a7565b8786866040518563ffffffff1660e01b8152600401612de19493929190614be0565b6020604051808303816000875af1925050508015612e1d57506040513d601f19601f82011682018060405250810190612e1a9190614c41565b60015b612e96573d8060008114612e4d576040519150601f19603f3d011682016040523d82523d6000602084013e612e52565b606091505b506000815103612e8e576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b612ef4816000613219565b50565b6060600b8054612f069061405f565b80601f0160208091040260200160405190810160405280929190818152602001828054612f329061405f565b8015612f7f5780601f10612f5457610100808354040283529160200191612f7f565b820191906000526020600020905b815481529060010190602001808311612f6257829003601f168201915b5050505050905090565b606060006001612f988461346b565b01905060008167ffffffffffffffff811115612fb757612fb6613b29565b5b6040519080825280601f01601f191660200182016040528015612fe95781602001600182028036833780820191505090505b509050600082602001820190505b60011561304c578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816130405761303f614c6e565b5b04945060008503612ff7575b819350505050919050565b60009392505050565b61306a8383612ac5565b60008373ffffffffffffffffffffffffffffffffffffffff163b146130f857600080549050600083820390505b6130aa6000868380600101945086612d99565b6130e0576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181106130975781600054146130f557600080fd5b50505b505050565b60006001821460e11b9050919050565b613115613600565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60008082905060005b845181101561320e576131f9828683815181106131ec576131eb6141a5565b5b60200260200101516135be565b91508080613206906141d4565b9150506131cc565b508091505092915050565b6000613224836128b8565b9050600081905060008061323786612984565b9150915084156132a057613253818461324e6128a7565b6129ab565b61329f57613268836132636128a7565b61267f565b61329e576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b6132ae8360008860016129ef565b80156132b957600082555b600160806001901b03600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506133618361331e856000886129f5565b7c02000000000000000000000000000000000000000000000000000000007c01000000000000000000000000000000000000000000000000000000001717612a1d565b600460008881526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008516036133e757600060018701905060006004600083815260200190815260200160002054036133e55760005481146133e4578460046000838152602001908152602001600020819055505b5b505b85600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4613451836000886001612a48565b600160008154809291906001019190505550505050505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106134c9577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816134bf576134be614c6e565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310613506576d04ee2d6d415b85acef810000000083816134fc576134fb614c6e565b5b0492506020810190505b662386f26fc10000831061353557662386f26fc10000838161352b5761352a614c6e565b5b0492506010810190505b6305f5e100831061355e576305f5e100838161355457613553614c6e565b5b0492506008810190505b612710831061358357612710838161357957613578614c6e565b5b0492506004810190505b606483106135a6576064838161359c5761359b614c6e565b5b0492506002810190505b600a83106135b5576001810190505b80915050919050565b60008183106135d6576135d182846135e9565b6135e1565b6135e083836135e9565b5b905092915050565b600082600052816020526040600020905092915050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61367681613663565b811461368157600080fd5b50565b6000813590506136938161366d565b92915050565b6000602082840312156136af576136ae613659565b5b60006136bd84828501613684565b91505092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6136fb816136c6565b811461370657600080fd5b50565b600081359050613718816136f2565b92915050565b60006020828403121561373457613733613659565b5b600061374284828501613709565b91505092915050565b60008115159050919050565b6137608161374b565b82525050565b600060208201905061377b6000830184613757565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156137bb5780820151818401526020810190506137a0565b60008484015250505050565b6000601f19601f8301169050919050565b60006137e382613781565b6137ed818561378c565b93506137fd81856020860161379d565b613806816137c7565b840191505092915050565b6000602082019050818103600083015261382b81846137d8565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061385e82613833565b9050919050565b61386e81613853565b82525050565b60006020820190506138896000830184613865565b92915050565b61389881613853565b81146138a357600080fd5b50565b6000813590506138b58161388f565b92915050565b600080604083850312156138d2576138d1613659565b5b60006138e0858286016138a6565b92505060206138f185828601613684565b9150509250929050565b61390481613663565b82525050565b600060208201905061391f60008301846138fb565b92915050565b60008060006060848603121561393e5761393d613659565b5b600061394c868287016138a6565b935050602061395d868287016138a6565b925050604061396e86828701613684565b9150509250925092565b6139818161374b565b811461398c57600080fd5b50565b60008135905061399e81613978565b92915050565b6000602082840312156139ba576139b9613659565b5b60006139c88482850161398f565b91505092915050565b6000819050919050565b6139e4816139d1565b82525050565b60006020820190506139ff60008301846139db565b92915050565b60008060408385031215613a1c57613a1b613659565b5b6000613a2a85828601613684565b9250506020613a3b858286016138a6565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112613a6a57613a69613a45565b5b8235905067ffffffffffffffff811115613a8757613a86613a4a565b5b602083019150836020820283011115613aa357613aa2613a4f565b5b9250929050565b60008060208385031215613ac157613ac0613659565b5b600083013567ffffffffffffffff811115613adf57613ade61365e565b5b613aeb85828601613a54565b92509250509250929050565b600060208284031215613b0d57613b0c613659565b5b6000613b1b848285016138a6565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613b61826137c7565b810181811067ffffffffffffffff82111715613b8057613b7f613b29565b5b80604052505050565b6000613b9361364f565b9050613b9f8282613b58565b919050565b600067ffffffffffffffff821115613bbf57613bbe613b29565b5b613bc8826137c7565b9050602081019050919050565b82818337600083830152505050565b6000613bf7613bf284613ba4565b613b89565b905082815260208101848484011115613c1357613c12613b24565b5b613c1e848285613bd5565b509392505050565b600082601f830112613c3b57613c3a613a45565b5b8135613c4b848260208601613be4565b91505092915050565b600060208284031215613c6a57613c69613659565b5b600082013567ffffffffffffffff811115613c8857613c8761365e565b5b613c9484828501613c26565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613cd281613663565b82525050565b6000613ce48383613cc9565b60208301905092915050565b6000602082019050919050565b6000613d0882613c9d565b613d128185613ca8565b9350613d1d83613cb9565b8060005b83811015613d4e578151613d358882613cd8565b9750613d4083613cf0565b925050600181019050613d21565b5085935050505092915050565b60006020820190508181036000830152613d758184613cfd565b905092915050565b60008083601f840112613d9357613d92613a45565b5b8235905067ffffffffffffffff811115613db057613daf613a4a565b5b602083019150836020820283011115613dcc57613dcb613a4f565b5b9250929050565b600080600060408486031215613dec57613deb613659565b5b6000613dfa86828701613684565b935050602084013567ffffffffffffffff811115613e1b57613e1a61365e565b5b613e2786828701613d7d565b92509250509250925092565b60008060408385031215613e4a57613e49613659565b5b6000613e58858286016138a6565b9250506020613e698582860161398f565b9150509250929050565b613e7c816139d1565b8114613e8757600080fd5b50565b600081359050613e9981613e73565b92915050565b600060208284031215613eb557613eb4613659565b5b6000613ec384828501613e8a565b91505092915050565b600067ffffffffffffffff821115613ee757613ee6613b29565b5b613ef0826137c7565b9050602081019050919050565b6000613f10613f0b84613ecc565b613b89565b905082815260208101848484011115613f2c57613f2b613b24565b5b613f37848285613bd5565b509392505050565b600082601f830112613f5457613f53613a45565b5b8135613f64848260208601613efd565b91505092915050565b60008060008060808587031215613f8757613f86613659565b5b6000613f95878288016138a6565b9450506020613fa6878288016138a6565b9350506040613fb787828801613684565b925050606085013567ffffffffffffffff811115613fd857613fd761365e565b5b613fe487828801613f3f565b91505092959194509250565b6000806040838503121561400757614006613659565b5b6000614015858286016138a6565b9250506020614026858286016138a6565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061407757607f821691505b60208210810361408a57614089614030565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006140ca82613663565b91506140d583613663565b92508282019050808211156140ed576140ec614090565b5b92915050565b7f4d617820737570706c7920657863656564656421000000000000000000000000600082015250565b600061412960148361378c565b9150614134826140f3565b602082019050919050565b600060208201905081810360008301526141588161411c565b9050919050565b600081905092915050565b50565b600061417a60008361415f565b91506141858261416a565b600082019050919050565b600061419b8261416d565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006141df82613663565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361421157614210614090565b5b600182019050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261427e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614241565b6142888683614241565b95508019841693508086168417925050509392505050565b6000819050919050565b60006142c56142c06142bb84613663565b6142a0565b613663565b9050919050565b6000819050919050565b6142df836142aa565b6142f36142eb826142cc565b84845461424e565b825550505050565b600090565b6143086142fb565b6143138184846142d6565b505050565b5b818110156143375761432c600082614300565b600181019050614319565b5050565b601f82111561437c5761434d8161421c565b61435684614231565b81016020851015614365578190505b61437961437185614231565b830182614318565b50505b505050565b600082821c905092915050565b600061439f60001984600802614381565b1980831691505092915050565b60006143b8838361438e565b9150826002028217905092915050565b6143d182613781565b67ffffffffffffffff8111156143ea576143e9613b29565b5b6143f4825461405f565b6143ff82828561433b565b600060209050601f8311600181146144325760008415614420578287015190505b61442a85826143ac565b865550614492565b601f1984166144408661421c565b60005b8281101561446857848901518255600182019150602085019450602081019050614443565b868310156144855784890151614481601f89168261438e565b8355505b6001600288020188555050505b505050505050565b7f54686520576c53616c6520697320706175736564210000000000000000000000600082015250565b60006144d060158361378c565b91506144db8261449a565b602082019050919050565b600060208201905081810360008301526144ff816144c3565b9050919050565b60008160601b9050919050565b600061451e82614506565b9050919050565b600061453082614513565b9050919050565b61454861454382613853565b614525565b82525050565b600061455a8284614537565b60148201915081905092915050565b7f496e76616c69642070726f6f6621000000000000000000000000000000000000600082015250565b600061459f600e8361378c565b91506145aa82614569565b602082019050919050565b600060208201905081810360008301526145ce81614592565b9050919050565b7f496e76616c6964206d696e7420616d6f756e7421000000000000000000000000600082015250565b600061460b60148361378c565b9150614616826145d5565b602082019050919050565b6000602082019050818103600083015261463a816145fe565b9050919050565b7f4d6178206d696e74207065722077616c6c657420657863656564656421000000600082015250565b6000614677601d8361378c565b915061468282614641565b602082019050919050565b600060208201905081810360008301526146a68161466a565b9050919050565b60006146b882613663565b91506146c383613663565b92508282026146d181613663565b915082820484148315176146e8576146e7614090565b5b5092915050565b7f496e73756666696369656e742066756e64732100000000000000000000000000600082015250565b600061472560138361378c565b9150614730826146ef565b602082019050919050565b6000602082019050818103600083015261475481614718565b9050919050565b7f546865205075626c696353616c65206973207061757365642100000000000000600082015250565b600061479160198361378c565b915061479c8261475b565b602082019050919050565b600060208201905081810360008301526147c081614784565b9050919050565b7f4275726e207068617365206e6f74207374617274656420796574000000000000600082015250565b60006147fd601a8361378c565b9150614808826147c7565b602082019050919050565b6000602082019050818103600083015261482c816147f0565b9050919050565b7f4e6f7420746865206f776e657221000000000000000000000000000000000000600082015250565b6000614869600e8361378c565b915061487482614833565b602082019050919050565b600060208201905081810360008301526148988161485c565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b60006148fb602f8361378c565b91506149068261489f565b604082019050919050565b6000602082019050818103600083015261492a816148ee565b9050919050565b600081905092915050565b600061494782613781565b6149518185614931565b935061496181856020860161379d565b80840191505092915050565b6000815461497a8161405f565b6149848186614931565b9450600182166000811461499f57600181146149b4576149e7565b60ff19831686528115158202860193506149e7565b6149bd8561421c565b60005b838110156149df578154818901526001820191506020810190506149c0565b838801955050505b50505092915050565b60006149fc828661493c565b9150614a08828561493c565b9150614a14828461496d565b9150819050949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614a7d60268361378c565b9150614a8882614a21565b604082019050919050565b60006020820190508181036000830152614aac81614a70565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614ae960208361378c565b9150614af482614ab3565b602082019050919050565b60006020820190508181036000830152614b1881614adc565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614b55601f8361378c565b9150614b6082614b1f565b602082019050919050565b60006020820190508181036000830152614b8481614b48565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614bb282614b8b565b614bbc8185614b96565b9350614bcc81856020860161379d565b614bd5816137c7565b840191505092915050565b6000608082019050614bf56000830187613865565b614c026020830186613865565b614c0f60408301856138fb565b8181036060830152614c218184614ba7565b905095945050505050565b600081519050614c3b816136f2565b92915050565b600060208284031215614c5757614c56613659565b5b6000614c6584828501614c2c565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea26469706673582212201864f9b224f1eff8358b07cd98b6c652fae5cbf25b7d1bb9528e15b4a66e7f0664736f6c6343000811003368747470733a2f2f6261667962656967617833737978626d6d6c76346b637468643361627663683575716c7a623273646132657834686f6736377176666b33357777692e697066732e6e667473746f726167652e6c696e6b2f72657665616c2e6a736f6e00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106103ac5760003560e01c8063869194ac116101e7578063b071401b1161010d578063e41f4673116100a0578063ee8b4ac61161006f578063ee8b4ac614610d8d578063f2cd579614610db8578063f2fde38b14610de3578063f648498014610e0c576103ac565b8063e41f467314610cbf578063e7873b5814610ce8578063e78b355314610d13578063e985e9c514610d50576103ac565b8063d9f0a671116100dc578063d9f0a67114610c19578063dc544ca714610c42578063e0a8085314610c6d578063e35b0ab114610c96576103ac565b8063b071401b14610b6e578063b88d4fde14610b97578063b90306ad14610bb3578063c87b56dd14610bdc576103ac565b80639cb257d011610185578063a28b56f211610154578063a28b56f214610ac6578063a45ba8e714610aef578063a4f4f8af14610b1a578063abe37a9414610b45576103ac565b80639cb257d014610a2d5780639fb17e3414610a56578063a035b1fe14610a72578063a22cb46514610a9d576103ac565b806393c7efbb116101c157806393c7efbb1461097e57806394354fd01461099a57806395d89b41146109c557806396330b5f146109f0576103ac565b8063869194ac146108ff5780638da5cb5b1461092a57806391b7f5ed14610955576103ac565b80633ccfd60b116102d75780635a0b8b231161026a57806370cad3aa1161023957806370cad3aa14610843578063715018a61461088057806378d45eef146108975780638462151c146108c2576103ac565b80635a0b8b23146107755780635c22abd2146107a05780636352211e146107c957806370a0823114610806576103ac565b806347d9569e116102a657806347d9569e146106bb57806349a79dd3146106e45780634fdd43cb14610721578063518302271461074a576103ac565b80633ccfd60b1461063457806342842e0e1461064b578063454bb2a814610667578063463fb32314610690576103ac565b806318160ddd1161034f5780632eb4a7ab1161031e5780632eb4a7ab1461058a5780632eba0dce146105b557806331ffd6f1146105de57806333bc1c5c14610609576103ac565b806318160ddd146104ef57806319d1997a1461051a57806323b872dd14610545578063287e4a7014610561576103ac565b806306fdde031161038b57806306fdde0314610442578063081812fc1461046d578063095ea7b3146104aa5780630e13a7c0146104c6576103ac565b806275770a146103b157806301ffc9a7146103da5780630284b5f414610417575b600080fd5b3480156103bd57600080fd5b506103d860048036038101906103d39190613699565b610e35565b005b3480156103e657600080fd5b5061040160048036038101906103fc919061371e565b610e47565b60405161040e9190613766565b60405180910390f35b34801561042357600080fd5b5061042c610ed9565b6040516104399190613811565b60405180910390f35b34801561044e57600080fd5b50610457610f67565b6040516104649190613811565b60405180910390f35b34801561047957600080fd5b50610494600480360381019061048f9190613699565b610ff9565b6040516104a19190613874565b60405180910390f35b6104c460048036038101906104bf91906138bb565b611078565b005b3480156104d257600080fd5b506104ed60048036038101906104e89190613699565b6111bc565b005b3480156104fb57600080fd5b506105046111ce565b604051610511919061390a565b60405180910390f35b34801561052657600080fd5b5061052f6111e5565b60405161053c919061390a565b60405180910390f35b61055f600480360381019061055a9190613925565b6111eb565b005b34801561056d57600080fd5b50610588600480360381019061058391906139a4565b61150d565b005b34801561059657600080fd5b5061059f611532565b6040516105ac91906139ea565b60405180910390f35b3480156105c157600080fd5b506105dc60048036038101906105d79190613a05565b611538565b005b3480156105ea57600080fd5b506105f36115a5565b6040516106009190613766565b60405180910390f35b34801561061557600080fd5b5061061e6115b8565b60405161062b9190613766565b60405180910390f35b34801561064057600080fd5b506106496115cb565b005b61066560048036038101906106609190613925565b611663565b005b34801561067357600080fd5b5061068e60048036038101906106899190613699565b611683565b005b34801561069c57600080fd5b506106a5611695565b6040516106b2919061390a565b60405180910390f35b3480156106c757600080fd5b506106e260048036038101906106dd9190613aaa565b61169b565b005b3480156106f057600080fd5b5061070b60048036038101906107069190613af7565b611751565b604051610718919061390a565b60405180910390f35b34801561072d57600080fd5b5061074860048036038101906107439190613c54565b611769565b005b34801561075657600080fd5b5061075f611784565b60405161076c9190613766565b60405180910390f35b34801561078157600080fd5b5061078a611797565b604051610797919061390a565b60405180910390f35b3480156107ac57600080fd5b506107c760048036038101906107c291906139a4565b61179d565b005b3480156107d557600080fd5b506107f060048036038101906107eb9190613699565b6117c2565b6040516107fd9190613874565b60405180910390f35b34801561081257600080fd5b5061082d60048036038101906108289190613af7565b6117d4565b60405161083a919061390a565b60405180910390f35b34801561084f57600080fd5b5061086a60048036038101906108659190613af7565b61188c565b604051610877919061390a565b60405180910390f35b34801561088c57600080fd5b506108956118a4565b005b3480156108a357600080fd5b506108ac6118b8565b6040516108b9919061390a565b60405180910390f35b3480156108ce57600080fd5b506108e960048036038101906108e49190613af7565b6118be565b6040516108f69190613d5b565b60405180910390f35b34801561090b57600080fd5b50610914611a02565b604051610921919061390a565b60405180910390f35b34801561093657600080fd5b5061093f611a08565b60405161094c9190613874565b60405180910390f35b34801561096157600080fd5b5061097c60048036038101906109779190613699565b611a32565b005b61099860048036038101906109939190613dd3565b611a44565b005b3480156109a657600080fd5b506109af611d5f565b6040516109bc919061390a565b60405180910390f35b3480156109d157600080fd5b506109da611d65565b6040516109e79190613811565b60405180910390f35b3480156109fc57600080fd5b50610a176004803603810190610a129190613af7565b611df7565b604051610a24919061390a565b60405180910390f35b348015610a3957600080fd5b50610a546004803603810190610a4f91906139a4565b611e0f565b005b610a706004803603810190610a6b9190613699565b611e34565b005b348015610a7e57600080fd5b50610a8761208d565b604051610a94919061390a565b60405180910390f35b348015610aa957600080fd5b50610ac46004803603810190610abf9190613e33565b612093565b005b348015610ad257600080fd5b50610aed6004803603810190610ae89190613e9f565b61219e565b005b348015610afb57600080fd5b50610b046121b0565b604051610b119190613811565b60405180910390f35b348015610b2657600080fd5b50610b2f61223e565b604051610b3c919061390a565b60405180910390f35b348015610b5157600080fd5b50610b6c6004803603810190610b679190613699565b612244565b005b348015610b7a57600080fd5b50610b956004803603810190610b909190613699565b612256565b005b610bb16004803603810190610bac9190613f6d565b612268565b005b348015610bbf57600080fd5b50610bda6004803603810190610bd59190613699565b6122db565b005b348015610be857600080fd5b50610c036004803603810190610bfe9190613699565b612484565b604051610c109190613811565b60405180910390f35b348015610c2557600080fd5b50610c406004803603810190610c3b9190613699565b6125dc565b005b348015610c4e57600080fd5b50610c576125ee565b604051610c64919061390a565b60405180910390f35b348015610c7957600080fd5b50610c946004803603810190610c8f91906139a4565b6125f4565b005b348015610ca257600080fd5b50610cbd6004803603810190610cb89190613699565b612619565b005b348015610ccb57600080fd5b50610ce66004803603810190610ce19190613c54565b61262b565b005b348015610cf457600080fd5b50610cfd612646565b604051610d0a919061390a565b60405180910390f35b348015610d1f57600080fd5b50610d3a6004803603810190610d359190613699565b61264c565b604051610d479190613874565b60405180910390f35b348015610d5c57600080fd5b50610d776004803603810190610d729190613ff0565b61267f565b604051610d849190613766565b60405180910390f35b348015610d9957600080fd5b50610da2612713565b604051610daf9190613766565b60405180910390f35b348015610dc457600080fd5b50610dcd612726565b604051610dda919061390a565b60405180910390f35b348015610def57600080fd5b50610e0a6004803603810190610e059190613af7565b61272c565b005b348015610e1857600080fd5b50610e336004803603810190610e2e9190613c54565b6127af565b005b610e3d6127ca565b8060108190555050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610ea257506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610ed25750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600c8054610ee69061405f565b80601f0160208091040260200160405190810160405280929190818152602001828054610f129061405f565b8015610f5f5780601f10610f3457610100808354040283529160200191610f5f565b820191906000526020600020905b815481529060010190602001808311610f4257829003601f168201915b505050505081565b606060028054610f769061405f565b80601f0160208091040260200160405190810160405280929190818152602001828054610fa29061405f565b8015610fef5780601f10610fc457610100808354040283529160200191610fef565b820191906000526020600020905b815481529060010190602001808311610fd257829003601f168201915b5050505050905090565b600061100482612848565b61103a576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000611083826117c2565b90508073ffffffffffffffffffffffffffffffffffffffff166110a46128a7565b73ffffffffffffffffffffffffffffffffffffffff1614611107576110d0816110cb6128a7565b61267f565b611106576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6111c46127ca565b80600f8190555050565b60006111d86128af565b6001546000540303905090565b60105481565b60006111f6826128b8565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461125d576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061126984612984565b9150915061127f818761127a6128a7565b6129ab565b6112cb576112948661128f6128a7565b61267f565b6112ca576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611331576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61133e86868660016129ef565b801561134957600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550611417856113f38888876129f5565b7c020000000000000000000000000000000000000000000000000000000017612a1d565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084160361149d576000600185019050600060046000838152602001908152602001600020540361149b57600054811461149a578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46115058686866001612a48565b505050505050565b6115156127ca565b80601660036101000a81548160ff02191690831515021790555050565b600a5481565b6115406127ca565b6010548261154c6111ce565b61155691906140bf565b1115611597576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158e9061413f565b60405180910390fd5b6115a18183612a4e565b5050565b601660009054906101000a900460ff1681565b601660019054906101000a900460ff1681565b6115d36127ca565b6115db612a6c565b60006115e5611a08565b73ffffffffffffffffffffffffffffffffffffffff164760405161160890614190565b60006040518083038185875af1925050503d8060008114611645576040519150601f19603f3d011682016040523d82523d6000602084013e61164a565b606091505b505090508061165857600080fd5b50611661612abb565b565b61167e83838360405180602001604052806000815250612268565b505050565b61168b6127ca565b8060158190555050565b601c5481565b6116a36127ca565b60005b8282905081101561174c5760105460146116be6111ce565b6116c891906140bf565b1115611709576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117009061413f565b60405180910390fd5b61173b83838381811061171f5761171e6141a5565b5b90506020020160208101906117349190613af7565b6014612ac5565b80611745906141d4565b90506116a6565b505050565b601a6020528060005260406000206000915090505481565b6117716127ca565b80600d908161178091906143c8565b5050565b601660029054906101000a900460ff1681565b60145481565b6117a56127ca565b80601660016101000a81548160ff02191690831515021790555050565b60006117cd826128b8565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361183b576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b60176020528060005260406000206000915090505481565b6118ac6127ca565b6118b66000612c80565b565b60115481565b606060006118cb836117d4565b67ffffffffffffffff8111156118e4576118e3613b29565b5b6040519080825280602002602001820160405280156119125781602001602082028036833780820191505090505b509050600061191f612d46565b905060008060005b838110156119f557600061193a82612d4f565b905080604001511561194c57506119e8565b600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff161461198c57806000015192505b8773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036119e657818685806001019650815181106119d9576119d86141a5565b5b6020026020010181815250505b505b8080600101915050611927565b5083945050505050919050565b60155481565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611a3a6127ca565b80600e8190555050565b601660009054906101000a900460ff16611a93576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8a906144e6565b60405180910390fd5b6000611a9d612d7a565b604051602001611aad919061454e565b604051602081830303815290604052805190602001209050611b13838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050600a5483612d82565b611b52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b49906145b5565b60405180910390fd5b600084118015611b6457506013548411155b611ba3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9a90614621565b60405180910390fd5b60115484611baf6111ce565b611bb991906140bf565b1115611bfa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf19061413f565b60405180910390fd5b60155484601760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611c4891906140bf565b1115611c89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c809061468d565b60405180910390fd5b83600f54611c9791906146ad565b341015611cd9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd09061473b565b60405180910390fd5b611cea611ce4612d7a565b85612a4e565b83601760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d3991906140bf565b9250508190555083601c6000828254611d5291906140bf565b9250508190555050505050565b60125481565b606060038054611d749061405f565b80601f0160208091040260200160405190810160405280929190818152602001828054611da09061405f565b8015611ded5780601f10611dc257610100808354040283529160200191611ded565b820191906000526020600020905b815481529060010190602001808311611dd057829003601f168201915b5050505050905090565b60186020528060005260406000206000915090505481565b611e176127ca565b80601660006101000a81548160ff02191690831515021790555050565b601660019054906101000a900460ff16611e83576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e7a906147a7565b60405180910390fd5b600081118015611e9557506012548111155b611ed4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ecb90614621565b60405180910390fd5b60105481611ee06111ce565b611eea91906140bf565b1115611f2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f229061413f565b60405180910390fd5b60145481601860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611f7991906140bf565b1115611fba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb19061468d565b60405180910390fd5b80600e54611fc891906146ad565b34101561200a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120019061473b565b60405180910390fd5b61201b612015612d7a565b82612a4e565b80601860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461206a91906140bf565b9250508190555080601b600082825461208391906140bf565b9250508190555050565b600e5481565b80600760006120a06128a7565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661214d6128a7565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516121929190613766565b60405180910390a35050565b6121a66127ca565b80600a8190555050565b600d80546121bd9061405f565b80601f01602080910402602001604051908101604052809291908181526020018280546121e99061405f565b80156122365780601f1061220b57610100808354040283529160200191612236565b820191906000526020600020905b81548152906001019060200180831161221957829003601f168201915b505050505081565b601b5481565b61224c6127ca565b8060138190555050565b61225e6127ca565b8060128190555050565b6122738484846111eb565b60008373ffffffffffffffffffffffffffffffffffffffff163b146122d55761229e84848484612d99565b6122d4576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b601660039054906101000a900460ff1661232a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161232190614813565b60405180910390fd5b612333816117c2565b73ffffffffffffffffffffffffffffffffffffffff16612351612d7a565b73ffffffffffffffffffffffffffffffffffffffff16146123a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161239e9061487f565b60405180910390fd5b6123b081612ee9565b6123b8612d7a565b6019600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001601a6000612417612d7a565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461246091906140bf565b925050819055506001601d600082825461247a91906140bf565b9250508190555050565b606061248f82612848565b6124ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124c590614911565b60405180910390fd5b60001515601660029054906101000a900460ff1615150361257b57600d80546124f69061405f565b80601f01602080910402602001604051908101604052809291908181526020018280546125229061405f565b801561256f5780601f106125445761010080835404028352916020019161256f565b820191906000526020600020905b81548152906001019060200180831161255257829003601f168201915b505050505090506125d7565b6000612585612ef7565b905060008151116125a557604051806020016040528060008152506125d3565b806125af84612f89565b600c6040516020016125c3939291906149f0565b6040516020818303038152906040525b9150505b919050565b6125e46127ca565b8060148190555050565b600f5481565b6125fc6127ca565b80601660026101000a81548160ff02191690831515021790555050565b6126216127ca565b8060118190555050565b6126336127ca565b80600c908161264291906143c8565b5050565b601d5481565b60196020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b601660039054906101000a900460ff1681565b60135481565b6127346127ca565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036127a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279a90614a93565b60405180910390fd5b6127ac81612c80565b50565b6127b76127ca565b80600b90816127c691906143c8565b5050565b6127d2612d7a565b73ffffffffffffffffffffffffffffffffffffffff166127f0611a08565b73ffffffffffffffffffffffffffffffffffffffff1614612846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161283d90614aff565b60405180910390fd5b565b6000816128536128af565b11158015612862575060005482105b80156128a0575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b60006001905090565b600080829050806128c76128af565b1161294d5760005481101561294c5760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082160361294a575b60008103612940576004600083600190039350838152602001908152602001600020549050612916565b809250505061297f565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8612a0c868684613057565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b612a68828260405180602001604052806000815250613060565b5050565b600260095403612ab1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612aa890614b6b565b60405180910390fd5b6002600981905550565b6001600981905550565b60008054905060008203612b05576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b1260008483856129ef565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612b8983612b7a60008660006129f5565b612b83856130fd565b17612a1d565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b818114612c2a57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612bef565b5060008203612c65576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050612c7b6000848385612a48565b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008054905090565b612d57613600565b612d73600460008481526020019081526020016000205461310d565b9050919050565b600033905090565b600082612d8f85846131c3565b1490509392505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612dbf6128a7565b8786866040518563ffffffff1660e01b8152600401612de19493929190614be0565b6020604051808303816000875af1925050508015612e1d57506040513d601f19601f82011682018060405250810190612e1a9190614c41565b60015b612e96573d8060008114612e4d576040519150601f19603f3d011682016040523d82523d6000602084013e612e52565b606091505b506000815103612e8e576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b612ef4816000613219565b50565b6060600b8054612f069061405f565b80601f0160208091040260200160405190810160405280929190818152602001828054612f329061405f565b8015612f7f5780601f10612f5457610100808354040283529160200191612f7f565b820191906000526020600020905b815481529060010190602001808311612f6257829003601f168201915b5050505050905090565b606060006001612f988461346b565b01905060008167ffffffffffffffff811115612fb757612fb6613b29565b5b6040519080825280601f01601f191660200182016040528015612fe95781602001600182028036833780820191505090505b509050600082602001820190505b60011561304c578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816130405761303f614c6e565b5b04945060008503612ff7575b819350505050919050565b60009392505050565b61306a8383612ac5565b60008373ffffffffffffffffffffffffffffffffffffffff163b146130f857600080549050600083820390505b6130aa6000868380600101945086612d99565b6130e0576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181106130975781600054146130f557600080fd5b50505b505050565b60006001821460e11b9050919050565b613115613600565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60008082905060005b845181101561320e576131f9828683815181106131ec576131eb6141a5565b5b60200260200101516135be565b91508080613206906141d4565b9150506131cc565b508091505092915050565b6000613224836128b8565b9050600081905060008061323786612984565b9150915084156132a057613253818461324e6128a7565b6129ab565b61329f57613268836132636128a7565b61267f565b61329e576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b6132ae8360008860016129ef565b80156132b957600082555b600160806001901b03600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506133618361331e856000886129f5565b7c02000000000000000000000000000000000000000000000000000000007c01000000000000000000000000000000000000000000000000000000001717612a1d565b600460008881526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008516036133e757600060018701905060006004600083815260200190815260200160002054036133e55760005481146133e4578460046000838152602001908152602001600020819055505b5b505b85600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4613451836000886001612a48565b600160008154809291906001019190505550505050505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106134c9577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816134bf576134be614c6e565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310613506576d04ee2d6d415b85acef810000000083816134fc576134fb614c6e565b5b0492506020810190505b662386f26fc10000831061353557662386f26fc10000838161352b5761352a614c6e565b5b0492506010810190505b6305f5e100831061355e576305f5e100838161355457613553614c6e565b5b0492506008810190505b612710831061358357612710838161357957613578614c6e565b5b0492506004810190505b606483106135a6576064838161359c5761359b614c6e565b5b0492506002810190505b600a83106135b5576001810190505b80915050919050565b60008183106135d6576135d182846135e9565b6135e1565b6135e083836135e9565b5b905092915050565b600082600052816020526040600020905092915050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61367681613663565b811461368157600080fd5b50565b6000813590506136938161366d565b92915050565b6000602082840312156136af576136ae613659565b5b60006136bd84828501613684565b91505092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6136fb816136c6565b811461370657600080fd5b50565b600081359050613718816136f2565b92915050565b60006020828403121561373457613733613659565b5b600061374284828501613709565b91505092915050565b60008115159050919050565b6137608161374b565b82525050565b600060208201905061377b6000830184613757565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156137bb5780820151818401526020810190506137a0565b60008484015250505050565b6000601f19601f8301169050919050565b60006137e382613781565b6137ed818561378c565b93506137fd81856020860161379d565b613806816137c7565b840191505092915050565b6000602082019050818103600083015261382b81846137d8565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061385e82613833565b9050919050565b61386e81613853565b82525050565b60006020820190506138896000830184613865565b92915050565b61389881613853565b81146138a357600080fd5b50565b6000813590506138b58161388f565b92915050565b600080604083850312156138d2576138d1613659565b5b60006138e0858286016138a6565b92505060206138f185828601613684565b9150509250929050565b61390481613663565b82525050565b600060208201905061391f60008301846138fb565b92915050565b60008060006060848603121561393e5761393d613659565b5b600061394c868287016138a6565b935050602061395d868287016138a6565b925050604061396e86828701613684565b9150509250925092565b6139818161374b565b811461398c57600080fd5b50565b60008135905061399e81613978565b92915050565b6000602082840312156139ba576139b9613659565b5b60006139c88482850161398f565b91505092915050565b6000819050919050565b6139e4816139d1565b82525050565b60006020820190506139ff60008301846139db565b92915050565b60008060408385031215613a1c57613a1b613659565b5b6000613a2a85828601613684565b9250506020613a3b858286016138a6565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112613a6a57613a69613a45565b5b8235905067ffffffffffffffff811115613a8757613a86613a4a565b5b602083019150836020820283011115613aa357613aa2613a4f565b5b9250929050565b60008060208385031215613ac157613ac0613659565b5b600083013567ffffffffffffffff811115613adf57613ade61365e565b5b613aeb85828601613a54565b92509250509250929050565b600060208284031215613b0d57613b0c613659565b5b6000613b1b848285016138a6565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613b61826137c7565b810181811067ffffffffffffffff82111715613b8057613b7f613b29565b5b80604052505050565b6000613b9361364f565b9050613b9f8282613b58565b919050565b600067ffffffffffffffff821115613bbf57613bbe613b29565b5b613bc8826137c7565b9050602081019050919050565b82818337600083830152505050565b6000613bf7613bf284613ba4565b613b89565b905082815260208101848484011115613c1357613c12613b24565b5b613c1e848285613bd5565b509392505050565b600082601f830112613c3b57613c3a613a45565b5b8135613c4b848260208601613be4565b91505092915050565b600060208284031215613c6a57613c69613659565b5b600082013567ffffffffffffffff811115613c8857613c8761365e565b5b613c9484828501613c26565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613cd281613663565b82525050565b6000613ce48383613cc9565b60208301905092915050565b6000602082019050919050565b6000613d0882613c9d565b613d128185613ca8565b9350613d1d83613cb9565b8060005b83811015613d4e578151613d358882613cd8565b9750613d4083613cf0565b925050600181019050613d21565b5085935050505092915050565b60006020820190508181036000830152613d758184613cfd565b905092915050565b60008083601f840112613d9357613d92613a45565b5b8235905067ffffffffffffffff811115613db057613daf613a4a565b5b602083019150836020820283011115613dcc57613dcb613a4f565b5b9250929050565b600080600060408486031215613dec57613deb613659565b5b6000613dfa86828701613684565b935050602084013567ffffffffffffffff811115613e1b57613e1a61365e565b5b613e2786828701613d7d565b92509250509250925092565b60008060408385031215613e4a57613e49613659565b5b6000613e58858286016138a6565b9250506020613e698582860161398f565b9150509250929050565b613e7c816139d1565b8114613e8757600080fd5b50565b600081359050613e9981613e73565b92915050565b600060208284031215613eb557613eb4613659565b5b6000613ec384828501613e8a565b91505092915050565b600067ffffffffffffffff821115613ee757613ee6613b29565b5b613ef0826137c7565b9050602081019050919050565b6000613f10613f0b84613ecc565b613b89565b905082815260208101848484011115613f2c57613f2b613b24565b5b613f37848285613bd5565b509392505050565b600082601f830112613f5457613f53613a45565b5b8135613f64848260208601613efd565b91505092915050565b60008060008060808587031215613f8757613f86613659565b5b6000613f95878288016138a6565b9450506020613fa6878288016138a6565b9350506040613fb787828801613684565b925050606085013567ffffffffffffffff811115613fd857613fd761365e565b5b613fe487828801613f3f565b91505092959194509250565b6000806040838503121561400757614006613659565b5b6000614015858286016138a6565b9250506020614026858286016138a6565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061407757607f821691505b60208210810361408a57614089614030565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006140ca82613663565b91506140d583613663565b92508282019050808211156140ed576140ec614090565b5b92915050565b7f4d617820737570706c7920657863656564656421000000000000000000000000600082015250565b600061412960148361378c565b9150614134826140f3565b602082019050919050565b600060208201905081810360008301526141588161411c565b9050919050565b600081905092915050565b50565b600061417a60008361415f565b91506141858261416a565b600082019050919050565b600061419b8261416d565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006141df82613663565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361421157614210614090565b5b600182019050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261427e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614241565b6142888683614241565b95508019841693508086168417925050509392505050565b6000819050919050565b60006142c56142c06142bb84613663565b6142a0565b613663565b9050919050565b6000819050919050565b6142df836142aa565b6142f36142eb826142cc565b84845461424e565b825550505050565b600090565b6143086142fb565b6143138184846142d6565b505050565b5b818110156143375761432c600082614300565b600181019050614319565b5050565b601f82111561437c5761434d8161421c565b61435684614231565b81016020851015614365578190505b61437961437185614231565b830182614318565b50505b505050565b600082821c905092915050565b600061439f60001984600802614381565b1980831691505092915050565b60006143b8838361438e565b9150826002028217905092915050565b6143d182613781565b67ffffffffffffffff8111156143ea576143e9613b29565b5b6143f4825461405f565b6143ff82828561433b565b600060209050601f8311600181146144325760008415614420578287015190505b61442a85826143ac565b865550614492565b601f1984166144408661421c565b60005b8281101561446857848901518255600182019150602085019450602081019050614443565b868310156144855784890151614481601f89168261438e565b8355505b6001600288020188555050505b505050505050565b7f54686520576c53616c6520697320706175736564210000000000000000000000600082015250565b60006144d060158361378c565b91506144db8261449a565b602082019050919050565b600060208201905081810360008301526144ff816144c3565b9050919050565b60008160601b9050919050565b600061451e82614506565b9050919050565b600061453082614513565b9050919050565b61454861454382613853565b614525565b82525050565b600061455a8284614537565b60148201915081905092915050565b7f496e76616c69642070726f6f6621000000000000000000000000000000000000600082015250565b600061459f600e8361378c565b91506145aa82614569565b602082019050919050565b600060208201905081810360008301526145ce81614592565b9050919050565b7f496e76616c6964206d696e7420616d6f756e7421000000000000000000000000600082015250565b600061460b60148361378c565b9150614616826145d5565b602082019050919050565b6000602082019050818103600083015261463a816145fe565b9050919050565b7f4d6178206d696e74207065722077616c6c657420657863656564656421000000600082015250565b6000614677601d8361378c565b915061468282614641565b602082019050919050565b600060208201905081810360008301526146a68161466a565b9050919050565b60006146b882613663565b91506146c383613663565b92508282026146d181613663565b915082820484148315176146e8576146e7614090565b5b5092915050565b7f496e73756666696369656e742066756e64732100000000000000000000000000600082015250565b600061472560138361378c565b9150614730826146ef565b602082019050919050565b6000602082019050818103600083015261475481614718565b9050919050565b7f546865205075626c696353616c65206973207061757365642100000000000000600082015250565b600061479160198361378c565b915061479c8261475b565b602082019050919050565b600060208201905081810360008301526147c081614784565b9050919050565b7f4275726e207068617365206e6f74207374617274656420796574000000000000600082015250565b60006147fd601a8361378c565b9150614808826147c7565b602082019050919050565b6000602082019050818103600083015261482c816147f0565b9050919050565b7f4e6f7420746865206f776e657221000000000000000000000000000000000000600082015250565b6000614869600e8361378c565b915061487482614833565b602082019050919050565b600060208201905081810360008301526148988161485c565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b60006148fb602f8361378c565b91506149068261489f565b604082019050919050565b6000602082019050818103600083015261492a816148ee565b9050919050565b600081905092915050565b600061494782613781565b6149518185614931565b935061496181856020860161379d565b80840191505092915050565b6000815461497a8161405f565b6149848186614931565b9450600182166000811461499f57600181146149b4576149e7565b60ff19831686528115158202860193506149e7565b6149bd8561421c565b60005b838110156149df578154818901526001820191506020810190506149c0565b838801955050505b50505092915050565b60006149fc828661493c565b9150614a08828561493c565b9150614a14828461496d565b9150819050949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614a7d60268361378c565b9150614a8882614a21565b604082019050919050565b60006020820190508181036000830152614aac81614a70565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614ae960208361378c565b9150614af482614ab3565b602082019050919050565b60006020820190508181036000830152614b1881614adc565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000614b55601f8361378c565b9150614b6082614b1f565b602082019050919050565b60006020820190508181036000830152614b8481614b48565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614bb282614b8b565b614bbc8185614b96565b9350614bcc81856020860161379d565b614bd5816137c7565b840191505092915050565b6000608082019050614bf56000830187613865565b614c026020830186613865565b614c0f60408301856138fb565b8181036060830152614c218184614ba7565b905095945050505050565b600081519050614c3b816136f2565b92915050565b600060208284031215614c5757614c56613659565b5b6000614c6584828501614c2c565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea26469706673582212201864f9b224f1eff8358b07cd98b6c652fae5cbf25b7d1bb9528e15b4a66e7f0664736f6c63430008110033

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

00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000

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

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


Deployed Bytecode Sourcemap

82809:7998:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88636:102;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;18404:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83027:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19306:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25797:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25230:408;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88525:86;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;15057:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83296:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;29436:2825;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88878:84;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82969:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85988:204;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83550:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83588:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;89112:172;;;;;;;;;;;;;:::i;:::-;;32357:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88289:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83969:23;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86200:238;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83866:64;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87358:132;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83625:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83464:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87513:95;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;20699:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16241:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83697:46;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69410:103;;;;;;;;;;;;;:::i;:::-;;83334:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;89432:712;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83505:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68762:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88441:78;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;84404:884;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83376:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19482:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83748:50;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87614:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85294:686;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83214:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26355:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87733:104;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83071:136;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83937:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87994:138;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87858:130;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;33148:407;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;86588:316;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;90251:449;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88157:126;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83253:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87059:81;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88744:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87236:116;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;84001:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83803:58;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26746:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83660:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83418:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69668:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;87154:76;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88636:102;68648:13;:11;:13::i;:::-;88720:12:::1;88706:11;:26;;;;88636:102:::0;:::o;18404:639::-;18489:4;18828:10;18813:25;;:11;:25;;;;:102;;;;18905:10;18890:25;;:11;:25;;;;18813:102;:179;;;;18982:10;18967:25;;:11;:25;;;;18813:179;18793:199;;18404:639;;;:::o;83027:37::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;19306:100::-;19360:13;19393:5;19386:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19306:100;:::o;25797:218::-;25873:7;25898:16;25906:7;25898;:16::i;:::-;25893:64;;25923:34;;;;;;;;;;;;;;25893:64;25977:15;:24;25993:7;25977:24;;;;;;;;;;;:30;;;;;;;;;;;;25970:37;;25797:218;;;:::o;25230:408::-;25319:13;25335:16;25343:7;25335;:16::i;:::-;25319:32;;25391:5;25368:28;;:19;:17;:19::i;:::-;:28;;;25364:175;;25416:44;25433:5;25440:19;:17;:19::i;:::-;25416:16;:44::i;:::-;25411:128;;25488:35;;;;;;;;;;;;;;25411:128;25364:175;25584:2;25551:15;:24;25567:7;25551:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;25622:7;25618:2;25602:28;;25611:5;25602:28;;;;;;;;;;;;25308:330;25230:408;;:::o;88525:86::-;68648:13;:11;:13::i;:::-;88597:8:::1;88587:7;:18;;;;88525:86:::0;:::o;15057:323::-;15118:7;15346:15;:13;:15::i;:::-;15331:12;;15315:13;;:28;:46;15308:53;;15057:323;:::o;83296:33::-;;;;:::o;29436:2825::-;29578:27;29608;29627:7;29608:18;:27::i;:::-;29578:57;;29693:4;29652:45;;29668:19;29652:45;;;29648:86;;29706:28;;;;;;;;;;;;;;29648:86;29748:27;29777:23;29804:35;29831:7;29804:26;:35::i;:::-;29747:92;;;;29939:68;29964:15;29981:4;29987:19;:17;:19::i;:::-;29939:24;:68::i;:::-;29934:180;;30027:43;30044:4;30050:19;:17;:19::i;:::-;30027:16;:43::i;:::-;30022:92;;30079:35;;;;;;;;;;;;;;30022:92;29934:180;30145:1;30131:16;;:2;:16;;;30127:52;;30156:23;;;;;;;;;;;;;;30127:52;30192:43;30214:4;30220:2;30224:7;30233:1;30192:21;:43::i;:::-;30328:15;30325:160;;;30468:1;30447:19;30440:30;30325:160;30865:18;:24;30884:4;30865:24;;;;;;;;;;;;;;;;30863:26;;;;;;;;;;;;30934:18;:22;30953:2;30934:22;;;;;;;;;;;;;;;;30932:24;;;;;;;;;;;31256:146;31293:2;31342:45;31357:4;31363:2;31367:19;31342:14;:45::i;:::-;11456:8;31314:73;31256:18;:146::i;:::-;31227:17;:26;31245:7;31227:26;;;;;;;;;;;:175;;;;31573:1;11456:8;31522:19;:47;:52;31518:627;;31595:19;31627:1;31617:7;:11;31595:33;;31784:1;31750:17;:30;31768:11;31750:30;;;;;;;;;;;;:35;31746:384;;31888:13;;31873:11;:28;31869:242;;32068:19;32035:17;:30;32053:11;32035:30;;;;;;;;;;;:52;;;;31869:242;31746:384;31576:569;31518:627;32192:7;32188:2;32173:27;;32182:4;32173:27;;;;;;;;;;;;32211:42;32232:4;32238:2;32242:7;32251:1;32211:20;:42::i;:::-;29567:2694;;;29436:2825;;;:::o;88878:84::-;68648:13;:11;:13::i;:::-;88950:6:::1;88937:10;;:19;;;;;;;;;;;;;;;;;;88878:84:::0;:::o;82969:25::-;;;;:::o;85988:204::-;68648:13;:11;:13::i;:::-;86110:11:::1;;86095;86079:13;:11;:13::i;:::-;:27;;;;:::i;:::-;:42;;86071:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;86153:33;86163:9;86174:11;86153:9;:33::i;:::-;85988:204:::0;;:::o;83550:33::-;;;;;;;;;;;;;:::o;83588:30::-;;;;;;;;;;;;;:::o;89112:172::-;68648:13;:11;:13::i;:::-;82133:21:::1;:19;:21::i;:::-;89192:7:::2;89213;:5;:7::i;:::-;89205:21;;89234;89205:55;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89191:69;;;89275:2;89267:11;;;::::0;::::2;;89162:122;82177:20:::1;:18;:20::i;:::-;89112:172::o:0;32357:193::-;32503:39;32520:4;32526:2;32530:7;32503:39;;;;;;;;;;;;:16;:39::i;:::-;32357:193;;;:::o;88289:134::-;68648:13;:11;:13::i;:::-;88397:20:::1;88375:19;:42;;;;88289:134:::0;:::o;83969:23::-;;;;:::o;86200:238::-;68648:13;:11;:13::i;:::-;86280:9:::1;86275:158;86295:9;;:16;;86291:1;:20;86275:158;;;86357:11;;86351:2;86335:13;:11;:13::i;:::-;:18;;;;:::i;:::-;:33;;86327:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;86402:23;86408:9;;86418:1;86408:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;86422:2;86402:5;:23::i;:::-;86313:3;;;;:::i;:::-;;;86275:158;;;;86200:238:::0;;:::o;83866:64::-;;;;;;;;;;;;;;;;;:::o;87358:132::-;68648:13;:11;:13::i;:::-;87466:18:::1;87446:17;:38;;;;;;:::i;:::-;;87358:132:::0;:::o;83625:28::-;;;;;;;;;;;;;:::o;83464:36::-;;;;:::o;87513:95::-;68648:13;:11;:13::i;:::-;87591:11:::1;87578:10;;:24;;;;;;;;;;;;;;;;;;87513:95:::0;:::o;20699:152::-;20771:7;20814:27;20833:7;20814:18;:27::i;:::-;20791:52;;20699:152;;;:::o;16241:233::-;16313:7;16354:1;16337:19;;:5;:19;;;16333:60;;16365:28;;;;;;;;;;;;;;16333:60;10400:13;16411:18;:25;16430:5;16411:25;;;;;;;;;;;;;;;;:55;16404:62;;16241:233;;;:::o;83697:46::-;;;;;;;;;;;;;;;;;:::o;69410:103::-;68648:13;:11;:13::i;:::-;69475:30:::1;69502:1;69475:18;:30::i;:::-;69410:103::o:0;83334:35::-;;;;:::o;89432:712::-;89493:16;89539:18;89574:16;89584:5;89574:9;:16::i;:::-;89560:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89539:52;;89603:11;89617:14;:12;:14::i;:::-;89603:28;;89642:19;89672:25;89713:9;89708:403;89728:3;89724:1;:7;89708:403;;;89753:31;89787:15;89800:1;89787:12;:15::i;:::-;89753:49;;89821:9;:16;;;89817:65;;;89858:8;;;89817:65;89926:1;89900:28;;:9;:14;;;:28;;;89896:103;;89969:9;:14;;;89949:34;;89896:103;90038:5;90017:26;;:17;:26;;;90013:87;;90083:1;90064;90066:13;;;;;;90064:16;;;;;;;;:::i;:::-;;;;;;;:20;;;;;90013:87;89738:373;89708:403;89733:3;;;;;;;89708:403;;;;90128:1;90121:8;;;;;;89432:712;;;:::o;83505:38::-;;;;:::o;68762:87::-;68808:7;68835:6;;;;;;;;;;;68828:13;;68762:87;:::o;88441:78::-;68648:13;:11;:13::i;:::-;88507:6:::1;88499:5;:14;;;;88441:78:::0;:::o;84404:884::-;84537:13;;;;;;;;;;;84529:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;84583:12;84625;:10;:12::i;:::-;84608:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;84598:41;;;;;;84583:56;;84654:50;84673:12;;84654:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84687:10;;84699:4;84654:18;:50::i;:::-;84646:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;84785:1;84771:11;:15;:54;;;;;84805:20;;84790:11;:35;;84771:54;84763:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;84896:13;;84881:11;84865:13;:11;:13::i;:::-;:27;;;;:::i;:::-;:44;;84857:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;84990:19;;84975:11;84949;:23;84961:10;84949:23;;;;;;;;;;;;;;;;:37;;;;:::i;:::-;:60;;84941:102;;;;;;;;;;;;:::i;:::-;;;;;;;;;85081:11;85071:7;;:21;;;;:::i;:::-;85058:9;:34;;85050:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;85144:36;85154:12;:10;:12::i;:::-;85168:11;85144:9;:36::i;:::-;85240:11;85213;:23;85225:10;85213:23;;;;;;;;;;;;;;;;:38;;;;;;;:::i;:::-;;;;;;;;85271:11;85259:8;;:23;;;;;;;:::i;:::-;;;;;;;;84489:799;84404:884;;;:::o;83376:37::-;;;;:::o;19482:104::-;19538:13;19571:7;19564:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19482:104;:::o;83748:50::-;;;;;;;;;;;;;;;;;:::o;87614:100::-;68648:13;:11;:13::i;:::-;87694:14:::1;87678:13;;:30;;;;;;;;;;;;;;;;;;87614:100:::0;:::o;85294:686::-;85400:10;;;;;;;;;;;85392:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;85469:1;85455:11;:15;:52;;;;;85489:18;;85474:11;:33;;85455:52;85447:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;85578:11;;85563;85547:13;:11;:13::i;:::-;:27;;;;:::i;:::-;:42;;85539:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;85674:17;;85659:11;85629:15;:27;85645:10;85629:27;;;;;;;;;;;;;;;;:41;;;;:::i;:::-;:62;;85621:104;;;;;;;;;;;;:::i;:::-;;;;;;;;;85761:11;85753:5;;:19;;;;:::i;:::-;85740:9;:32;;85732:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;85824:36;85834:12;:10;:12::i;:::-;85848:11;85824:9;:36::i;:::-;85924:11;85893:15;:27;85909:10;85893:27;;;;;;;;;;;;;;;;:42;;;;;;;:::i;:::-;;;;;;;;85960:11;85944:12;;:27;;;;;;;:::i;:::-;;;;;;;;85294:686;:::o;83214:34::-;;;;:::o;26355:234::-;26502:8;26450:18;:39;26469:19;:17;:19::i;:::-;26450:39;;;;;;;;;;;;;;;:49;26490:8;26450:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;26562:8;26526:55;;26541:19;:17;:19::i;:::-;26526:55;;;26572:8;26526:55;;;;;;:::i;:::-;;;;;;;;26355:234;;:::o;87733:104::-;68648:13;:11;:13::i;:::-;87820:11:::1;87807:10;:24;;;;87733:104:::0;:::o;83071:136::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;83937:27::-;;;;:::o;87994:138::-;68648:13;:11;:13::i;:::-;88105:21:::1;88082:20;:44;;;;87994:138:::0;:::o;87858:130::-;68648:13;:11;:13::i;:::-;87963:19:::1;87942:18;:40;;;;87858:130:::0;:::o;33148:407::-;33323:31;33336:4;33342:2;33346:7;33323:12;:31::i;:::-;33387:1;33369:2;:14;;;:19;33365:183;;33408:56;33439:4;33445:2;33449:7;33458:5;33408:30;:56::i;:::-;33403:145;;33492:40;;;;;;;;;;;;;;33403:145;33365:183;33148:407;;;;:::o;86588:316::-;86640:10;;;;;;;;;;;86632:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;86711:17;86719:8;86711:7;:17::i;:::-;86695:33;;:12;:10;:12::i;:::-;:33;;;86687:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;86755:15;86761:8;86755:5;:15::i;:::-;86811:12;:10;:12::i;:::-;86776:22;:32;86799:8;86776:32;;;;;;;;;;;;:47;;;;;;;;;;;;;;;;;;86876:1;86829:29;:43;86859:12;:10;:12::i;:::-;86829:43;;;;;;;;;;;;;;;;:48;;;;;;;:::i;:::-;;;;;;;;86898:1;86883:12;;:16;;;;;;;:::i;:::-;;;;;;;;86588:316;:::o;90251:449::-;90325:13;90355:17;90363:8;90355:7;:17::i;:::-;90347:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;90449:5;90437:17;;:8;;;;;;;;;;;:17;;;90433:64;;90472:17;90465:24;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90433:64;90505:28;90536:10;:8;:10::i;:::-;90505:41;;90591:1;90566:14;90560:28;:32;:134;;;;;;;;;;;;;;;;;90628:14;90644:19;:8;:17;:19::i;:::-;90665:13;90611:68;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;90560:134;90553:141;;;90251:449;;;;:::o;88157:126::-;68648:13;:11;:13::i;:::-;88259:18:::1;88239:17;:38;;;;88157:126:::0;:::o;83253:36::-;;;;:::o;87059:81::-;68648:13;:11;:13::i;:::-;87128:6:::1;87117:8;;:17;;;;;;;;;;;;;;;;;;87059:81:::0;:::o;88744:110::-;68648:13;:11;:13::i;:::-;88834:14:::1;88818:13;:30;;;;88744:110:::0;:::o;87236:116::-;68648:13;:11;:13::i;:::-;87332:14:::1;87316:13;:30;;;;;;:::i;:::-;;87236:116:::0;:::o;84001:27::-;;;;:::o;83803:58::-;;;;;;;;;;;;;;;;;;;;;;:::o;26746:164::-;26843:4;26867:18;:25;26886:5;26867:25;;;;;;;;;;;;;;;:35;26893:8;26867:35;;;;;;;;;;;;;;;;;;;;;;;;;26860:42;;26746:164;;;;:::o;83660:30::-;;;;;;;;;;;;;:::o;83418:39::-;;;;:::o;69668:201::-;68648:13;:11;:13::i;:::-;69777:1:::1;69757:22;;:8;:22;;::::0;69749:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;69833:28;69852:8;69833:18;:28::i;:::-;69668:201:::0;:::o;87154:76::-;68648:13;:11;:13::i;:::-;87220:4:::1;87214:3;:10;;;;;;:::i;:::-;;87154:76:::0;:::o;68927:132::-;69002:12;:10;:12::i;:::-;68991:23;;:7;:5;:7::i;:::-;:23;;;68983:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;68927:132::o;27168:282::-;27233:4;27289:7;27270:15;:13;:15::i;:::-;:26;;:66;;;;;27323:13;;27313:7;:23;27270:66;:153;;;;;27422:1;11176:8;27374:17;:26;27392:7;27374:26;;;;;;;;;;;;:44;:49;27270:153;27250:173;;27168:282;;;:::o;49476:105::-;49536:7;49563:10;49556:17;;49476:105;:::o;90150:95::-;90215:7;90238:1;90231:8;;90150:95;:::o;21854:1275::-;21921:7;21941:12;21956:7;21941:22;;22024:4;22005:15;:13;:15::i;:::-;:23;22001:1061;;22058:13;;22051:4;:20;22047:1015;;;22096:14;22113:17;:23;22131:4;22113:23;;;;;;;;;;;;22096:40;;22230:1;11176:8;22202:6;:24;:29;22198:845;;22867:113;22884:1;22874:6;:11;22867:113;;22927:17;:25;22945:6;;;;;;;22927:25;;;;;;;;;;;;22918:34;;22867:113;;;23013:6;23006:13;;;;;;22198:845;22073:989;22047:1015;22001:1061;23090:31;;;;;;;;;;;;;;21854:1275;;;;:::o;28331:485::-;28433:27;28462:23;28503:38;28544:15;:24;28560:7;28544:24;;;;;;;;;;;28503:65;;28721:18;28698:41;;28778:19;28772:26;28753:45;;28683:126;28331:485;;;:::o;27559:659::-;27708:11;27873:16;27866:5;27862:28;27853:37;;28033:16;28022:9;28018:32;28005:45;;28183:15;28172:9;28169:30;28161:5;28150:9;28147:20;28144:56;28134:66;;27559:659;;;;;:::o;34217:159::-;;;;;:::o;48785:311::-;48920:7;48940:16;11580:3;48966:19;:41;;48940:68;;11580:3;49034:31;49045:4;49051:2;49055:9;49034:10;:31::i;:::-;49026:40;;:62;;49019:69;;;48785:311;;;;;:::o;23677:450::-;23757:14;23925:16;23918:5;23914:28;23905:37;;24102:5;24088:11;24063:23;24059:41;24056:52;24049:5;24046:63;24036:73;;23677:450;;;;:::o;35041:158::-;;;;;:::o;43308:112::-;43385:27;43395:2;43399:8;43385:27;;;;;;;;;;;;:9;:27::i;:::-;43308:112;;:::o;82213:293::-;81615:1;82347:7;;:19;82339:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;81615:1;82480:7;:18;;;;82213:293::o;82514:213::-;81571:1;82697:7;:22;;;;82514:213::o;36817:2966::-;36890:20;36913:13;;36890:36;;36953:1;36941:8;:13;36937:44;;36963:18;;;;;;;;;;;;;;36937:44;36994:61;37024:1;37028:2;37032:12;37046:8;36994:21;:61::i;:::-;37538:1;10538:2;37508:1;:26;;37507:32;37495:8;:45;37469:18;:22;37488:2;37469:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;37817:139;37854:2;37908:33;37931:1;37935:2;37939:1;37908:14;:33::i;:::-;37875:30;37896:8;37875:20;:30::i;:::-;:66;37817:18;:139::i;:::-;37783:17;:31;37801:12;37783:31;;;;;;;;;;;:173;;;;37973:16;38004:11;38033:8;38018:12;:23;38004:37;;38554:16;38550:2;38546:25;38534:37;;38926:12;38886:8;38845:1;38783:25;38724:1;38663;38636:335;39297:1;39283:12;39279:20;39237:346;39338:3;39329:7;39326:16;39237:346;;39556:7;39546:8;39543:1;39516:25;39513:1;39510;39505:59;39391:1;39382:7;39378:15;39367:26;;39237:346;;;39241:77;39628:1;39616:8;:13;39612:45;;39638:19;;;;;;;;;;;;;;39612:45;39690:3;39674:13;:19;;;;37243:2462;;39715:60;39744:1;39748:2;39752:12;39766:8;39715:20;:60::i;:::-;36879:2904;36817:2966;;:::o;70029:191::-;70103:16;70122:6;;;;;;;;;;;70103:25;;70148:8;70139:6;;:17;;;;;;;;;;;;;;;;;;70203:8;70172:40;;70193:8;70172:40;;;;;;;;;;;;70092:128;70029:191;:::o;14744:103::-;14799:7;14826:13;;14819:20;;14744:103;:::o;21302:161::-;21370:21;;:::i;:::-;21411:44;21430:17;:24;21448:5;21430:24;;;;;;;;;;;;21411:18;:44::i;:::-;21404:51;;21302:161;;;:::o;67313:98::-;67366:7;67393:10;67386:17;;67313:98;:::o;71449:190::-;71574:4;71627;71598:25;71611:5;71618:4;71598:12;:25::i;:::-;:33;71591:40;;71449:190;;;;;:::o;35639:716::-;35802:4;35848:2;35823:45;;;35869:19;:17;:19::i;:::-;35890:4;35896:7;35905:5;35823:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;35819:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36123:1;36106:6;:13;:18;36102:235;;36152:40;;;;;;;;;;;;;;36102:235;36295:6;36289:13;36280:6;36276:2;36272:15;36265:38;35819:529;35992:54;;;35982:64;;;:6;:64;;;;35975:71;;;35639:716;;;;;;:::o;43687:89::-;43747:21;43753:7;43762:5;43747;:21::i;:::-;43687:89;:::o;90706:98::-;90766:13;90795:3;90788:10;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90706:98;:::o;64740:716::-;64796:13;64847:14;64884:1;64864:17;64875:5;64864:10;:17::i;:::-;:21;64847:38;;64900:20;64934:6;64923:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64900:41;;64956:11;65085:6;65081:2;65077:15;65069:6;65065:28;65058:35;;65122:288;65129:4;65122:288;;;65154:5;;;;;;;;65296:8;65291:2;65284:5;65280:14;65275:30;65270:3;65262:44;65352:2;65343:11;;;;;;:::i;:::-;;;;;65386:1;65377:5;:10;65122:288;65373:21;65122:288;65431:6;65424:13;;;;;64740:716;;;:::o;48486:147::-;48623:6;48486:147;;;;;:::o;42535:689::-;42666:19;42672:2;42676:8;42666:5;:19::i;:::-;42745:1;42727:2;:14;;;:19;42723:483;;42767:11;42781:13;;42767:27;;42813:13;42835:8;42829:3;:14;42813:30;;42862:233;42893:62;42932:1;42936:2;42940:7;;;;;;42949:5;42893:30;:62::i;:::-;42888:167;;42991:40;;;;;;;;;;;;;;42888:167;43090:3;43082:5;:11;42862:233;;43177:3;43160:13;;:20;43156:34;;43182:8;;;43156:34;42748:458;;42723:483;42535:689;;;:::o;24229:324::-;24299:14;24532:1;24522:8;24519:15;24493:24;24489:46;24479:56;;24229:324;;;:::o;23228:366::-;23294:31;;:::i;:::-;23371:6;23338:9;:14;;:41;;;;;;;;;;;11059:3;23424:6;:33;;23390:9;:24;;:68;;;;;;;;;;;23516:1;11176:8;23488:6;:24;:29;;23469:9;:16;;:48;;;;;;;;;;;11580:3;23557:6;:28;;23528:9;:19;;:58;;;;;;;;;;;23228:366;;;:::o;72316:296::-;72399:7;72419:20;72442:4;72419:27;;72462:9;72457:118;72481:5;:12;72477:1;:16;72457:118;;;72530:33;72540:12;72554:5;72560:1;72554:8;;;;;;;;:::i;:::-;;;;;;;;72530:9;:33::i;:::-;72515:48;;72495:3;;;;;:::i;:::-;;;;72457:118;;;;72592:12;72585:19;;;72316:296;;;;:::o;44005:3081::-;44085:27;44115;44134:7;44115:18;:27::i;:::-;44085:57;;44155:12;44186:19;44155:52;;44221:27;44250:23;44277:35;44304:7;44277:26;:35::i;:::-;44220:92;;;;44329:13;44325:316;;;44450:68;44475:15;44492:4;44498:19;:17;:19::i;:::-;44450:24;:68::i;:::-;44445:184;;44542:43;44559:4;44565:19;:17;:19::i;:::-;44542:16;:43::i;:::-;44537:92;;44594:35;;;;;;;;;;;;;;44537:92;44445:184;44325:316;44653:51;44675:4;44689:1;44693:7;44702:1;44653:21;:51::i;:::-;44797:15;44794:160;;;44937:1;44916:19;44909:30;44794:160;45615:1;10665:3;45585:1;:26;;45584:32;45556:18;:24;45575:4;45556:24;;;;;;;;;;;;;;;;:60;;;;;;;;;;;45883:176;45920:4;45991:53;46006:4;46020:1;46024:19;45991:14;:53::i;:::-;11456:8;11176;45944:43;45943:101;45883:18;:176::i;:::-;45854:17;:26;45872:7;45854:26;;;;;;;;;;;:205;;;;46230:1;11456:8;46179:19;:47;:52;46175:627;;46252:19;46284:1;46274:7;:11;46252:33;;46441:1;46407:17;:30;46425:11;46407:30;;;;;;;;;;;;:35;46403:384;;46545:13;;46530:11;:28;46526:242;;46725:19;46692:17;:30;46710:11;46692:30;;;;;;;;;;;:52;;;;46526:242;46403:384;46233:569;46175:627;46857:7;46853:1;46830:35;;46839:4;46830:35;;;;;;;;;;;;46876:50;46897:4;46911:1;46915:7;46924:1;46876:20;:50::i;:::-;47053:12;;:14;;;;;;;;;;;;;44074:3012;;;;44005:3081;;:::o;61606:922::-;61659:7;61679:14;61696:1;61679:18;;61746:6;61737:5;:15;61733:102;;61782:6;61773:15;;;;;;:::i;:::-;;;;;61817:2;61807:12;;;;61733:102;61862:6;61853:5;:15;61849:102;;61898:6;61889:15;;;;;;:::i;:::-;;;;;61933:2;61923:12;;;;61849:102;61978:6;61969:5;:15;61965:102;;62014:6;62005:15;;;;;;:::i;:::-;;;;;62049:2;62039:12;;;;61965:102;62094:5;62085;:14;62081:99;;62129:5;62120:14;;;;;;:::i;:::-;;;;;62163:1;62153:11;;;;62081:99;62207:5;62198;:14;62194:99;;62242:5;62233:14;;;;;;:::i;:::-;;;;;62276:1;62266:11;;;;62194:99;62320:5;62311;:14;62307:99;;62355:5;62346:14;;;;;;:::i;:::-;;;;;62389:1;62379:11;;;;62307:99;62433:5;62424;:14;62420:66;;62469:1;62459:11;;;;62420:66;62514:6;62507:13;;;61606:922;;;:::o;79356:149::-;79419:7;79450:1;79446;:5;:51;;79477:20;79492:1;79495;79477:14;:20::i;:::-;79446:51;;;79454:20;79469:1;79472;79454:14;:20::i;:::-;79446:51;79439:58;;79356:149;;;;:::o;79513:268::-;79581:13;79688:1;79682:4;79675:15;79717:1;79711:4;79704:15;79758:4;79752;79742:21;79733:30;;79513:268;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:139::-;591:5;629:6;616:20;607:29;;645:33;672:5;645:33;:::i;:::-;545:139;;;;:::o;690:329::-;749:6;798:2;786:9;777:7;773:23;769:32;766:119;;;804:79;;:::i;:::-;766:119;924:1;949:53;994:7;985:6;974:9;970:22;949:53;:::i;:::-;939:63;;895:117;690:329;;;;:::o;1025:149::-;1061:7;1101:66;1094:5;1090:78;1079:89;;1025:149;;;:::o;1180:120::-;1252:23;1269:5;1252:23;:::i;:::-;1245:5;1242:34;1232:62;;1290:1;1287;1280:12;1232:62;1180:120;:::o;1306:137::-;1351:5;1389:6;1376:20;1367:29;;1405:32;1431:5;1405:32;:::i;:::-;1306:137;;;;:::o;1449:327::-;1507:6;1556:2;1544:9;1535:7;1531:23;1527:32;1524:119;;;1562:79;;:::i;:::-;1524:119;1682:1;1707:52;1751:7;1742:6;1731:9;1727:22;1707:52;:::i;:::-;1697:62;;1653:116;1449:327;;;;:::o;1782:90::-;1816:7;1859:5;1852:13;1845:21;1834:32;;1782:90;;;:::o;1878:109::-;1959:21;1974:5;1959:21;:::i;:::-;1954:3;1947:34;1878:109;;:::o;1993:210::-;2080:4;2118:2;2107:9;2103:18;2095:26;;2131:65;2193:1;2182:9;2178:17;2169:6;2131:65;:::i;:::-;1993:210;;;;:::o;2209:99::-;2261:6;2295:5;2289:12;2279:22;;2209:99;;;:::o;2314:169::-;2398:11;2432:6;2427:3;2420:19;2472:4;2467:3;2463:14;2448:29;;2314:169;;;;:::o;2489:246::-;2570:1;2580:113;2594:6;2591:1;2588:13;2580:113;;;2679:1;2674:3;2670:11;2664:18;2660:1;2655:3;2651:11;2644:39;2616:2;2613:1;2609:10;2604:15;;2580:113;;;2727:1;2718:6;2713:3;2709:16;2702:27;2551:184;2489:246;;;:::o;2741:102::-;2782:6;2833:2;2829:7;2824:2;2817:5;2813:14;2809:28;2799:38;;2741:102;;;:::o;2849:377::-;2937:3;2965:39;2998:5;2965:39;:::i;:::-;3020:71;3084:6;3079:3;3020:71;:::i;:::-;3013:78;;3100:65;3158:6;3153:3;3146:4;3139:5;3135:16;3100:65;:::i;:::-;3190:29;3212:6;3190:29;:::i;:::-;3185:3;3181:39;3174:46;;2941:285;2849:377;;;;:::o;3232:313::-;3345:4;3383:2;3372:9;3368:18;3360:26;;3432:9;3426:4;3422:20;3418:1;3407:9;3403:17;3396:47;3460:78;3533:4;3524:6;3460:78;:::i;:::-;3452:86;;3232:313;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:118::-;4977:24;4995:5;4977:24;:::i;:::-;4972:3;4965:37;4890:118;;:::o;5014:222::-;5107:4;5145:2;5134:9;5130:18;5122:26;;5158:71;5226:1;5215:9;5211:17;5202:6;5158:71;:::i;:::-;5014:222;;;;:::o;5242:619::-;5319:6;5327;5335;5384:2;5372:9;5363:7;5359:23;5355:32;5352:119;;;5390:79;;:::i;:::-;5352:119;5510:1;5535:53;5580:7;5571:6;5560:9;5556:22;5535:53;:::i;:::-;5525:63;;5481:117;5637:2;5663:53;5708:7;5699:6;5688:9;5684:22;5663:53;:::i;:::-;5653:63;;5608:118;5765:2;5791:53;5836:7;5827:6;5816:9;5812:22;5791:53;:::i;:::-;5781:63;;5736:118;5242:619;;;;;:::o;5867:116::-;5937:21;5952:5;5937:21;:::i;:::-;5930:5;5927:32;5917:60;;5973:1;5970;5963:12;5917:60;5867:116;:::o;5989:133::-;6032:5;6070:6;6057:20;6048:29;;6086:30;6110:5;6086:30;:::i;:::-;5989:133;;;;:::o;6128:323::-;6184:6;6233:2;6221:9;6212:7;6208:23;6204:32;6201:119;;;6239:79;;:::i;:::-;6201:119;6359:1;6384:50;6426:7;6417:6;6406:9;6402:22;6384:50;:::i;:::-;6374:60;;6330:114;6128:323;;;;:::o;6457:77::-;6494:7;6523:5;6512:16;;6457:77;;;:::o;6540:118::-;6627:24;6645:5;6627:24;:::i;:::-;6622:3;6615:37;6540:118;;:::o;6664:222::-;6757:4;6795:2;6784:9;6780:18;6772:26;;6808:71;6876:1;6865:9;6861:17;6852:6;6808:71;:::i;:::-;6664:222;;;;:::o;6892:474::-;6960:6;6968;7017:2;7005:9;6996:7;6992:23;6988:32;6985:119;;;7023:79;;:::i;:::-;6985:119;7143:1;7168:53;7213:7;7204:6;7193:9;7189:22;7168:53;:::i;:::-;7158:63;;7114:117;7270:2;7296:53;7341:7;7332:6;7321:9;7317:22;7296:53;:::i;:::-;7286:63;;7241:118;6892:474;;;;;:::o;7372:117::-;7481:1;7478;7471:12;7495:117;7604:1;7601;7594:12;7618:117;7727:1;7724;7717:12;7758:568;7831:8;7841:6;7891:3;7884:4;7876:6;7872:17;7868:27;7858:122;;7899:79;;:::i;:::-;7858:122;8012:6;7999:20;7989:30;;8042:18;8034:6;8031:30;8028:117;;;8064:79;;:::i;:::-;8028:117;8178:4;8170:6;8166:17;8154:29;;8232:3;8224:4;8216:6;8212:17;8202:8;8198:32;8195:41;8192:128;;;8239:79;;:::i;:::-;8192:128;7758:568;;;;;:::o;8332:559::-;8418:6;8426;8475:2;8463:9;8454:7;8450:23;8446:32;8443:119;;;8481:79;;:::i;:::-;8443:119;8629:1;8618:9;8614:17;8601:31;8659:18;8651:6;8648:30;8645:117;;;8681:79;;:::i;:::-;8645:117;8794:80;8866:7;8857:6;8846:9;8842:22;8794:80;:::i;:::-;8776:98;;;;8572:312;8332:559;;;;;:::o;8897:329::-;8956:6;9005:2;8993:9;8984:7;8980:23;8976:32;8973:119;;;9011:79;;:::i;:::-;8973:119;9131:1;9156:53;9201:7;9192:6;9181:9;9177:22;9156:53;:::i;:::-;9146:63;;9102:117;8897:329;;;;:::o;9232:117::-;9341:1;9338;9331:12;9355:180;9403:77;9400:1;9393:88;9500:4;9497:1;9490:15;9524:4;9521:1;9514:15;9541:281;9624:27;9646:4;9624:27;:::i;:::-;9616:6;9612:40;9754:6;9742:10;9739:22;9718:18;9706:10;9703:34;9700:62;9697:88;;;9765:18;;:::i;:::-;9697:88;9805:10;9801:2;9794:22;9584:238;9541:281;;:::o;9828:129::-;9862:6;9889:20;;:::i;:::-;9879:30;;9918:33;9946:4;9938:6;9918:33;:::i;:::-;9828:129;;;:::o;9963:308::-;10025:4;10115:18;10107:6;10104:30;10101:56;;;10137:18;;:::i;:::-;10101:56;10175:29;10197:6;10175:29;:::i;:::-;10167:37;;10259:4;10253;10249:15;10241:23;;9963:308;;;:::o;10277:146::-;10374:6;10369:3;10364;10351:30;10415:1;10406:6;10401:3;10397:16;10390:27;10277:146;;;:::o;10429:425::-;10507:5;10532:66;10548:49;10590:6;10548:49;:::i;:::-;10532:66;:::i;:::-;10523:75;;10621:6;10614:5;10607:21;10659:4;10652:5;10648:16;10697:3;10688:6;10683:3;10679:16;10676:25;10673:112;;;10704:79;;:::i;:::-;10673:112;10794:54;10841:6;10836:3;10831;10794:54;:::i;:::-;10513:341;10429:425;;;;;:::o;10874:340::-;10930:5;10979:3;10972:4;10964:6;10960:17;10956:27;10946:122;;10987:79;;:::i;:::-;10946:122;11104:6;11091:20;11129:79;11204:3;11196:6;11189:4;11181:6;11177:17;11129:79;:::i;:::-;11120:88;;10936:278;10874:340;;;;:::o;11220:509::-;11289:6;11338:2;11326:9;11317:7;11313:23;11309:32;11306:119;;;11344:79;;:::i;:::-;11306:119;11492:1;11481:9;11477:17;11464:31;11522:18;11514:6;11511:30;11508:117;;;11544:79;;:::i;:::-;11508:117;11649:63;11704:7;11695:6;11684:9;11680:22;11649:63;:::i;:::-;11639:73;;11435:287;11220:509;;;;:::o;11735:114::-;11802:6;11836:5;11830:12;11820:22;;11735:114;;;:::o;11855:184::-;11954:11;11988:6;11983:3;11976:19;12028:4;12023:3;12019:14;12004:29;;11855:184;;;;:::o;12045:132::-;12112:4;12135:3;12127:11;;12165:4;12160:3;12156:14;12148:22;;12045:132;;;:::o;12183:108::-;12260:24;12278:5;12260:24;:::i;:::-;12255:3;12248:37;12183:108;;:::o;12297:179::-;12366:10;12387:46;12429:3;12421:6;12387:46;:::i;:::-;12465:4;12460:3;12456:14;12442:28;;12297:179;;;;:::o;12482:113::-;12552:4;12584;12579:3;12575:14;12567:22;;12482:113;;;:::o;12631:732::-;12750:3;12779:54;12827:5;12779:54;:::i;:::-;12849:86;12928:6;12923:3;12849:86;:::i;:::-;12842:93;;12959:56;13009:5;12959:56;:::i;:::-;13038:7;13069:1;13054:284;13079:6;13076:1;13073:13;13054:284;;;13155:6;13149:13;13182:63;13241:3;13226:13;13182:63;:::i;:::-;13175:70;;13268:60;13321:6;13268:60;:::i;:::-;13258:70;;13114:224;13101:1;13098;13094:9;13089:14;;13054:284;;;13058:14;13354:3;13347:10;;12755:608;;;12631:732;;;;:::o;13369:373::-;13512:4;13550:2;13539:9;13535:18;13527:26;;13599:9;13593:4;13589:20;13585:1;13574:9;13570:17;13563:47;13627:108;13730:4;13721:6;13627:108;:::i;:::-;13619:116;;13369:373;;;;:::o;13765:568::-;13838:8;13848:6;13898:3;13891:4;13883:6;13879:17;13875:27;13865:122;;13906:79;;:::i;:::-;13865:122;14019:6;14006:20;13996:30;;14049:18;14041:6;14038:30;14035:117;;;14071:79;;:::i;:::-;14035:117;14185:4;14177:6;14173:17;14161:29;;14239:3;14231:4;14223:6;14219:17;14209:8;14205:32;14202:41;14199:128;;;14246:79;;:::i;:::-;14199:128;13765:568;;;;;:::o;14339:704::-;14434:6;14442;14450;14499:2;14487:9;14478:7;14474:23;14470:32;14467:119;;;14505:79;;:::i;:::-;14467:119;14625:1;14650:53;14695:7;14686:6;14675:9;14671:22;14650:53;:::i;:::-;14640:63;;14596:117;14780:2;14769:9;14765:18;14752:32;14811:18;14803:6;14800:30;14797:117;;;14833:79;;:::i;:::-;14797:117;14946:80;15018:7;15009:6;14998:9;14994:22;14946:80;:::i;:::-;14928:98;;;;14723:313;14339:704;;;;;:::o;15049:468::-;15114:6;15122;15171:2;15159:9;15150:7;15146:23;15142:32;15139:119;;;15177:79;;:::i;:::-;15139:119;15297:1;15322:53;15367:7;15358:6;15347:9;15343:22;15322:53;:::i;:::-;15312:63;;15268:117;15424:2;15450:50;15492:7;15483:6;15472:9;15468:22;15450:50;:::i;:::-;15440:60;;15395:115;15049:468;;;;;:::o;15523:122::-;15596:24;15614:5;15596:24;:::i;:::-;15589:5;15586:35;15576:63;;15635:1;15632;15625:12;15576:63;15523:122;:::o;15651:139::-;15697:5;15735:6;15722:20;15713:29;;15751:33;15778:5;15751:33;:::i;:::-;15651:139;;;;:::o;15796:329::-;15855:6;15904:2;15892:9;15883:7;15879:23;15875:32;15872:119;;;15910:79;;:::i;:::-;15872:119;16030:1;16055:53;16100:7;16091:6;16080:9;16076:22;16055:53;:::i;:::-;16045:63;;16001:117;15796:329;;;;:::o;16131:307::-;16192:4;16282:18;16274:6;16271:30;16268:56;;;16304:18;;:::i;:::-;16268:56;16342:29;16364:6;16342:29;:::i;:::-;16334:37;;16426:4;16420;16416:15;16408:23;;16131:307;;;:::o;16444:423::-;16521:5;16546:65;16562:48;16603:6;16562:48;:::i;:::-;16546:65;:::i;:::-;16537:74;;16634:6;16627:5;16620:21;16672:4;16665:5;16661:16;16710:3;16701:6;16696:3;16692:16;16689:25;16686:112;;;16717:79;;:::i;:::-;16686:112;16807:54;16854:6;16849:3;16844;16807:54;:::i;:::-;16527:340;16444:423;;;;;:::o;16886:338::-;16941:5;16990:3;16983:4;16975:6;16971:17;16967:27;16957:122;;16998:79;;:::i;:::-;16957:122;17115:6;17102:20;17140:78;17214:3;17206:6;17199:4;17191:6;17187:17;17140:78;:::i;:::-;17131:87;;16947:277;16886:338;;;;:::o;17230:943::-;17325:6;17333;17341;17349;17398:3;17386:9;17377:7;17373:23;17369:33;17366:120;;;17405:79;;:::i;:::-;17366:120;17525:1;17550:53;17595:7;17586:6;17575:9;17571:22;17550:53;:::i;:::-;17540:63;;17496:117;17652:2;17678:53;17723:7;17714:6;17703:9;17699:22;17678:53;:::i;:::-;17668:63;;17623:118;17780:2;17806:53;17851:7;17842:6;17831:9;17827:22;17806:53;:::i;:::-;17796:63;;17751:118;17936:2;17925:9;17921:18;17908:32;17967:18;17959:6;17956:30;17953:117;;;17989:79;;:::i;:::-;17953:117;18094:62;18148:7;18139:6;18128:9;18124:22;18094:62;:::i;:::-;18084:72;;17879:287;17230:943;;;;;;;:::o;18179:474::-;18247:6;18255;18304:2;18292:9;18283:7;18279:23;18275:32;18272:119;;;18310:79;;:::i;:::-;18272:119;18430:1;18455:53;18500:7;18491:6;18480:9;18476:22;18455:53;:::i;:::-;18445:63;;18401:117;18557:2;18583:53;18628:7;18619:6;18608:9;18604:22;18583:53;:::i;:::-;18573:63;;18528:118;18179:474;;;;;:::o;18659:180::-;18707:77;18704:1;18697:88;18804:4;18801:1;18794:15;18828:4;18825:1;18818:15;18845:320;18889:6;18926:1;18920:4;18916:12;18906:22;;18973:1;18967:4;18963:12;18994:18;18984:81;;19050:4;19042:6;19038:17;19028:27;;18984:81;19112:2;19104:6;19101:14;19081:18;19078:38;19075:84;;19131:18;;:::i;:::-;19075:84;18896:269;18845:320;;;:::o;19171:180::-;19219:77;19216:1;19209:88;19316:4;19313:1;19306:15;19340:4;19337:1;19330:15;19357:191;19397:3;19416:20;19434:1;19416:20;:::i;:::-;19411:25;;19450:20;19468:1;19450:20;:::i;:::-;19445:25;;19493:1;19490;19486:9;19479:16;;19514:3;19511:1;19508:10;19505:36;;;19521:18;;:::i;:::-;19505:36;19357:191;;;;:::o;19554:170::-;19694:22;19690:1;19682:6;19678:14;19671:46;19554:170;:::o;19730:366::-;19872:3;19893:67;19957:2;19952:3;19893:67;:::i;:::-;19886:74;;19969:93;20058:3;19969:93;:::i;:::-;20087:2;20082:3;20078:12;20071:19;;19730:366;;;:::o;20102:419::-;20268:4;20306:2;20295:9;20291:18;20283:26;;20355:9;20349:4;20345:20;20341:1;20330:9;20326:17;20319:47;20383:131;20509:4;20383:131;:::i;:::-;20375:139;;20102:419;;;:::o;20527:147::-;20628:11;20665:3;20650:18;;20527:147;;;;:::o;20680:114::-;;:::o;20800:398::-;20959:3;20980:83;21061:1;21056:3;20980:83;:::i;:::-;20973:90;;21072:93;21161:3;21072:93;:::i;:::-;21190:1;21185:3;21181:11;21174:18;;20800:398;;;:::o;21204:379::-;21388:3;21410:147;21553:3;21410:147;:::i;:::-;21403:154;;21574:3;21567:10;;21204:379;;;:::o;21589:180::-;21637:77;21634:1;21627:88;21734:4;21731:1;21724:15;21758:4;21755:1;21748:15;21775:233;21814:3;21837:24;21855:5;21837:24;:::i;:::-;21828:33;;21883:66;21876:5;21873:77;21870:103;;21953:18;;:::i;:::-;21870:103;22000:1;21993:5;21989:13;21982:20;;21775:233;;;:::o;22014:141::-;22063:4;22086:3;22078:11;;22109:3;22106:1;22099:14;22143:4;22140:1;22130:18;22122:26;;22014:141;;;:::o;22161:93::-;22198:6;22245:2;22240;22233:5;22229:14;22225:23;22215:33;;22161:93;;;:::o;22260:107::-;22304:8;22354:5;22348:4;22344:16;22323:37;;22260:107;;;;:::o;22373:393::-;22442:6;22492:1;22480:10;22476:18;22515:97;22545:66;22534:9;22515:97;:::i;:::-;22633:39;22663:8;22652:9;22633:39;:::i;:::-;22621:51;;22705:4;22701:9;22694:5;22690:21;22681:30;;22754:4;22744:8;22740:19;22733:5;22730:30;22720:40;;22449:317;;22373:393;;;;;:::o;22772:60::-;22800:3;22821:5;22814:12;;22772:60;;;:::o;22838:142::-;22888:9;22921:53;22939:34;22948:24;22966:5;22948:24;:::i;:::-;22939:34;:::i;:::-;22921:53;:::i;:::-;22908:66;;22838:142;;;:::o;22986:75::-;23029:3;23050:5;23043:12;;22986:75;;;:::o;23067:269::-;23177:39;23208:7;23177:39;:::i;:::-;23238:91;23287:41;23311:16;23287:41;:::i;:::-;23279:6;23272:4;23266:11;23238:91;:::i;:::-;23232:4;23225:105;23143:193;23067:269;;;:::o;23342:73::-;23387:3;23342:73;:::o;23421:189::-;23498:32;;:::i;:::-;23539:65;23597:6;23589;23583:4;23539:65;:::i;:::-;23474:136;23421:189;;:::o;23616:186::-;23676:120;23693:3;23686:5;23683:14;23676:120;;;23747:39;23784:1;23777:5;23747:39;:::i;:::-;23720:1;23713:5;23709:13;23700:22;;23676:120;;;23616:186;;:::o;23808:543::-;23909:2;23904:3;23901:11;23898:446;;;23943:38;23975:5;23943:38;:::i;:::-;24027:29;24045:10;24027:29;:::i;:::-;24017:8;24013:44;24210:2;24198:10;24195:18;24192:49;;;24231:8;24216:23;;24192:49;24254:80;24310:22;24328:3;24310:22;:::i;:::-;24300:8;24296:37;24283:11;24254:80;:::i;:::-;23913:431;;23898:446;23808:543;;;:::o;24357:117::-;24411:8;24461:5;24455:4;24451:16;24430:37;;24357:117;;;;:::o;24480:169::-;24524:6;24557:51;24605:1;24601:6;24593:5;24590:1;24586:13;24557:51;:::i;:::-;24553:56;24638:4;24632;24628:15;24618:25;;24531:118;24480:169;;;;:::o;24654:295::-;24730:4;24876:29;24901:3;24895:4;24876:29;:::i;:::-;24868:37;;24938:3;24935:1;24931:11;24925:4;24922:21;24914:29;;24654:295;;;;:::o;24954:1395::-;25071:37;25104:3;25071:37;:::i;:::-;25173:18;25165:6;25162:30;25159:56;;;25195:18;;:::i;:::-;25159:56;25239:38;25271:4;25265:11;25239:38;:::i;:::-;25324:67;25384:6;25376;25370:4;25324:67;:::i;:::-;25418:1;25442:4;25429:17;;25474:2;25466:6;25463:14;25491:1;25486:618;;;;26148:1;26165:6;26162:77;;;26214:9;26209:3;26205:19;26199:26;26190:35;;26162:77;26265:67;26325:6;26318:5;26265:67;:::i;:::-;26259:4;26252:81;26121:222;25456:887;;25486:618;25538:4;25534:9;25526:6;25522:22;25572:37;25604:4;25572:37;:::i;:::-;25631:1;25645:208;25659:7;25656:1;25653:14;25645:208;;;25738:9;25733:3;25729:19;25723:26;25715:6;25708:42;25789:1;25781:6;25777:14;25767:24;;25836:2;25825:9;25821:18;25808:31;;25682:4;25679:1;25675:12;25670:17;;25645:208;;;25881:6;25872:7;25869:19;25866:179;;;25939:9;25934:3;25930:19;25924:26;25982:48;26024:4;26016:6;26012:17;26001:9;25982:48;:::i;:::-;25974:6;25967:64;25889:156;25866:179;26091:1;26087;26079:6;26075:14;26071:22;26065:4;26058:36;25493:611;;;25456:887;;25046:1303;;;24954:1395;;:::o;26355:171::-;26495:23;26491:1;26483:6;26479:14;26472:47;26355:171;:::o;26532:366::-;26674:3;26695:67;26759:2;26754:3;26695:67;:::i;:::-;26688:74;;26771:93;26860:3;26771:93;:::i;:::-;26889:2;26884:3;26880:12;26873:19;;26532:366;;;:::o;26904:419::-;27070:4;27108:2;27097:9;27093:18;27085:26;;27157:9;27151:4;27147:20;27143:1;27132:9;27128:17;27121:47;27185:131;27311:4;27185:131;:::i;:::-;27177:139;;26904:419;;;:::o;27329:94::-;27362:8;27410:5;27406:2;27402:14;27381:35;;27329:94;;;:::o;27429:::-;27468:7;27497:20;27511:5;27497:20;:::i;:::-;27486:31;;27429:94;;;:::o;27529:100::-;27568:7;27597:26;27617:5;27597:26;:::i;:::-;27586:37;;27529:100;;;:::o;27635:157::-;27740:45;27760:24;27778:5;27760:24;:::i;:::-;27740:45;:::i;:::-;27735:3;27728:58;27635:157;;:::o;27798:256::-;27910:3;27925:75;27996:3;27987:6;27925:75;:::i;:::-;28025:2;28020:3;28016:12;28009:19;;28045:3;28038:10;;27798:256;;;;:::o;28060:164::-;28200:16;28196:1;28188:6;28184:14;28177:40;28060:164;:::o;28230:366::-;28372:3;28393:67;28457:2;28452:3;28393:67;:::i;:::-;28386:74;;28469:93;28558:3;28469:93;:::i;:::-;28587:2;28582:3;28578:12;28571:19;;28230:366;;;:::o;28602:419::-;28768:4;28806:2;28795:9;28791:18;28783:26;;28855:9;28849:4;28845:20;28841:1;28830:9;28826:17;28819:47;28883:131;29009:4;28883:131;:::i;:::-;28875:139;;28602:419;;;:::o;29027:170::-;29167:22;29163:1;29155:6;29151:14;29144:46;29027:170;:::o;29203:366::-;29345:3;29366:67;29430:2;29425:3;29366:67;:::i;:::-;29359:74;;29442:93;29531:3;29442:93;:::i;:::-;29560:2;29555:3;29551:12;29544:19;;29203:366;;;:::o;29575:419::-;29741:4;29779:2;29768:9;29764:18;29756:26;;29828:9;29822:4;29818:20;29814:1;29803:9;29799:17;29792:47;29856:131;29982:4;29856:131;:::i;:::-;29848:139;;29575:419;;;:::o;30000:179::-;30140:31;30136:1;30128:6;30124:14;30117:55;30000:179;:::o;30185:366::-;30327:3;30348:67;30412:2;30407:3;30348:67;:::i;:::-;30341:74;;30424:93;30513:3;30424:93;:::i;:::-;30542:2;30537:3;30533:12;30526:19;;30185:366;;;:::o;30557:419::-;30723:4;30761:2;30750:9;30746:18;30738:26;;30810:9;30804:4;30800:20;30796:1;30785:9;30781:17;30774:47;30838:131;30964:4;30838:131;:::i;:::-;30830:139;;30557:419;;;:::o;30982:410::-;31022:7;31045:20;31063:1;31045:20;:::i;:::-;31040:25;;31079:20;31097:1;31079:20;:::i;:::-;31074:25;;31134:1;31131;31127:9;31156:30;31174:11;31156:30;:::i;:::-;31145:41;;31335:1;31326:7;31322:15;31319:1;31316:22;31296:1;31289:9;31269:83;31246:139;;31365:18;;:::i;:::-;31246:139;31030:362;30982:410;;;;:::o;31398:169::-;31538:21;31534:1;31526:6;31522:14;31515:45;31398:169;:::o;31573:366::-;31715:3;31736:67;31800:2;31795:3;31736:67;:::i;:::-;31729:74;;31812:93;31901:3;31812:93;:::i;:::-;31930:2;31925:3;31921:12;31914:19;;31573:366;;;:::o;31945:419::-;32111:4;32149:2;32138:9;32134:18;32126:26;;32198:9;32192:4;32188:20;32184:1;32173:9;32169:17;32162:47;32226:131;32352:4;32226:131;:::i;:::-;32218:139;;31945:419;;;:::o;32370:175::-;32510:27;32506:1;32498:6;32494:14;32487:51;32370:175;:::o;32551:366::-;32693:3;32714:67;32778:2;32773:3;32714:67;:::i;:::-;32707:74;;32790:93;32879:3;32790:93;:::i;:::-;32908:2;32903:3;32899:12;32892:19;;32551:366;;;:::o;32923:419::-;33089:4;33127:2;33116:9;33112:18;33104:26;;33176:9;33170:4;33166:20;33162:1;33151:9;33147:17;33140:47;33204:131;33330:4;33204:131;:::i;:::-;33196:139;;32923:419;;;:::o;33348:176::-;33488:28;33484:1;33476:6;33472:14;33465:52;33348:176;:::o;33530:366::-;33672:3;33693:67;33757:2;33752:3;33693:67;:::i;:::-;33686:74;;33769:93;33858:3;33769:93;:::i;:::-;33887:2;33882:3;33878:12;33871:19;;33530:366;;;:::o;33902:419::-;34068:4;34106:2;34095:9;34091:18;34083:26;;34155:9;34149:4;34145:20;34141:1;34130:9;34126:17;34119:47;34183:131;34309:4;34183:131;:::i;:::-;34175:139;;33902:419;;;:::o;34327:164::-;34467:16;34463:1;34455:6;34451:14;34444:40;34327:164;:::o;34497:366::-;34639:3;34660:67;34724:2;34719:3;34660:67;:::i;:::-;34653:74;;34736:93;34825:3;34736:93;:::i;:::-;34854:2;34849:3;34845:12;34838:19;;34497:366;;;:::o;34869:419::-;35035:4;35073:2;35062:9;35058:18;35050:26;;35122:9;35116:4;35112:20;35108:1;35097:9;35093:17;35086:47;35150:131;35276:4;35150:131;:::i;:::-;35142:139;;34869:419;;;:::o;35294:234::-;35434:34;35430:1;35422:6;35418:14;35411:58;35503:17;35498:2;35490:6;35486:15;35479:42;35294:234;:::o;35534:366::-;35676:3;35697:67;35761:2;35756:3;35697:67;:::i;:::-;35690:74;;35773:93;35862:3;35773:93;:::i;:::-;35891:2;35886:3;35882:12;35875:19;;35534:366;;;:::o;35906:419::-;36072:4;36110:2;36099:9;36095:18;36087:26;;36159:9;36153:4;36149:20;36145:1;36134:9;36130:17;36123:47;36187:131;36313:4;36187:131;:::i;:::-;36179:139;;35906:419;;;:::o;36331:148::-;36433:11;36470:3;36455:18;;36331:148;;;;:::o;36485:390::-;36591:3;36619:39;36652:5;36619:39;:::i;:::-;36674:89;36756:6;36751:3;36674:89;:::i;:::-;36667:96;;36772:65;36830:6;36825:3;36818:4;36811:5;36807:16;36772:65;:::i;:::-;36862:6;36857:3;36853:16;36846:23;;36595:280;36485:390;;;;:::o;36905:874::-;37008:3;37045:5;37039:12;37074:36;37100:9;37074:36;:::i;:::-;37126:89;37208:6;37203:3;37126:89;:::i;:::-;37119:96;;37246:1;37235:9;37231:17;37262:1;37257:166;;;;37437:1;37432:341;;;;37224:549;;37257:166;37341:4;37337:9;37326;37322:25;37317:3;37310:38;37403:6;37396:14;37389:22;37381:6;37377:35;37372:3;37368:45;37361:52;;37257:166;;37432:341;37499:38;37531:5;37499:38;:::i;:::-;37559:1;37573:154;37587:6;37584:1;37581:13;37573:154;;;37661:7;37655:14;37651:1;37646:3;37642:11;37635:35;37711:1;37702:7;37698:15;37687:26;;37609:4;37606:1;37602:12;37597:17;;37573:154;;;37756:6;37751:3;37747:16;37740:23;;37439:334;;37224:549;;37012:767;;36905:874;;;;:::o;37785:589::-;38010:3;38032:95;38123:3;38114:6;38032:95;:::i;:::-;38025:102;;38144:95;38235:3;38226:6;38144:95;:::i;:::-;38137:102;;38256:92;38344:3;38335:6;38256:92;:::i;:::-;38249:99;;38365:3;38358:10;;37785:589;;;;;;:::o;38380:225::-;38520:34;38516:1;38508:6;38504:14;38497:58;38589:8;38584:2;38576:6;38572:15;38565:33;38380:225;:::o;38611:366::-;38753:3;38774:67;38838:2;38833:3;38774:67;:::i;:::-;38767:74;;38850:93;38939:3;38850:93;:::i;:::-;38968:2;38963:3;38959:12;38952:19;;38611:366;;;:::o;38983:419::-;39149:4;39187:2;39176:9;39172:18;39164:26;;39236:9;39230:4;39226:20;39222:1;39211:9;39207:17;39200:47;39264:131;39390:4;39264:131;:::i;:::-;39256:139;;38983:419;;;:::o;39408:182::-;39548:34;39544:1;39536:6;39532:14;39525:58;39408:182;:::o;39596:366::-;39738:3;39759:67;39823:2;39818:3;39759:67;:::i;:::-;39752:74;;39835:93;39924:3;39835:93;:::i;:::-;39953:2;39948:3;39944:12;39937:19;;39596:366;;;:::o;39968:419::-;40134:4;40172:2;40161:9;40157:18;40149:26;;40221:9;40215:4;40211:20;40207:1;40196:9;40192:17;40185:47;40249:131;40375:4;40249:131;:::i;:::-;40241:139;;39968:419;;;:::o;40393:181::-;40533:33;40529:1;40521:6;40517:14;40510:57;40393:181;:::o;40580:366::-;40722:3;40743:67;40807:2;40802:3;40743:67;:::i;:::-;40736:74;;40819:93;40908:3;40819:93;:::i;:::-;40937:2;40932:3;40928:12;40921:19;;40580:366;;;:::o;40952:419::-;41118:4;41156:2;41145:9;41141:18;41133:26;;41205:9;41199:4;41195:20;41191:1;41180:9;41176:17;41169:47;41233:131;41359:4;41233:131;:::i;:::-;41225:139;;40952:419;;;:::o;41377:98::-;41428:6;41462:5;41456:12;41446:22;;41377:98;;;:::o;41481:168::-;41564:11;41598:6;41593:3;41586:19;41638:4;41633:3;41629:14;41614:29;;41481:168;;;;:::o;41655:373::-;41741:3;41769:38;41801:5;41769:38;:::i;:::-;41823:70;41886:6;41881:3;41823:70;:::i;:::-;41816:77;;41902:65;41960:6;41955:3;41948:4;41941:5;41937:16;41902:65;:::i;:::-;41992:29;42014:6;41992:29;:::i;:::-;41987:3;41983:39;41976:46;;41745:283;41655:373;;;;:::o;42034:640::-;42229:4;42267:3;42256:9;42252:19;42244:27;;42281:71;42349:1;42338:9;42334:17;42325:6;42281:71;:::i;:::-;42362:72;42430:2;42419:9;42415:18;42406:6;42362:72;:::i;:::-;42444;42512:2;42501:9;42497:18;42488:6;42444:72;:::i;:::-;42563:9;42557:4;42553:20;42548:2;42537:9;42533:18;42526:48;42591:76;42662:4;42653:6;42591:76;:::i;:::-;42583:84;;42034:640;;;;;;;:::o;42680:141::-;42736:5;42767:6;42761:13;42752:22;;42783:32;42809:5;42783:32;:::i;:::-;42680:141;;;;:::o;42827:349::-;42896:6;42945:2;42933:9;42924:7;42920:23;42916:32;42913:119;;;42951:79;;:::i;:::-;42913:119;43071:1;43096:63;43151:7;43142:6;43131:9;43127:22;43096:63;:::i;:::-;43086:73;;43042:127;42827:349;;;;:::o;43182:180::-;43230:77;43227:1;43220:88;43327:4;43324:1;43317:15;43351:4;43348:1;43341:15

Swarm Source

ipfs://1864f9b224f1eff8358b07cd98b6c652fae5cbf25b7d1bb9528e15b4a66e7f06
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.