ETH Price: $3,433.02 (+3.58%)

Token

OrigamiClub (OGClub)
 

Overview

Max Total Supply

1,000 OGClub

Holders

437

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
1 OGClub
0x6b768b4496d56eb18207d1138806df542a29960b
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:
OrigamiClub

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: MIT
// File: IOperatorFilterRegistry.sol

pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator)
        external
        view
        returns (bool);

    function register(address registrant) external;

    function registerAndSubscribe(address registrant, address subscription)
        external;

    function registerAndCopyEntries(
        address registrant,
        address registrantToCopy
    ) external;

    function unregister(address addr) external;

    function updateOperator(
        address registrant,
        address operator,
        bool filtered
    ) external;

    function updateOperators(
        address registrant,
        address[] calldata operators,
        bool filtered
    ) external;

    function updateCodeHash(
        address registrant,
        bytes32 codehash,
        bool filtered
    ) external;

    function updateCodeHashes(
        address registrant,
        bytes32[] calldata codeHashes,
        bool filtered
    ) external;

    function subscribe(address registrant, address registrantToSubscribe)
        external;

    function unsubscribe(address registrant, bool copyExistingEntries) external;

    function subscriptionOf(address addr) external returns (address registrant);

    function subscribers(address registrant)
        external
        returns (address[] memory);

    function subscriberAt(address registrant, uint256 index)
        external
        returns (address);

    function copyEntriesOf(address registrant, address registrantToCopy)
        external;

    function isOperatorFiltered(address registrant, address operator)
        external
        returns (bool);

    function isCodeHashOfFiltered(address registrant, address operatorWithCode)
        external
        returns (bool);

    function isCodeHashFiltered(address registrant, bytes32 codeHash)
        external
        returns (bool);

    function filteredOperators(address addr)
        external
        returns (address[] memory);

    function filteredCodeHashes(address addr)
        external
        returns (bytes32[] memory);

    function filteredOperatorAt(address registrant, uint256 index)
        external
        returns (address);

    function filteredCodeHashAt(address registrant, uint256 index)
        external
        returns (bytes32);

    function isRegistered(address addr) external returns (bool);

    function codeHashOf(address addr) external returns (bytes32);
}

// File: OperatorFilterer.sol

pragma solidity ^0.8.13;

/**
 * @title  OperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 */
abstract contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

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

    modifier onlyAllowedOperator(address from) virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            // Allow spending tokens from addresses with balance
            // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
            // from an EOA.
            if (from == msg.sender) {
                _;
                return;
            }
            if (
                !OPERATOR_FILTER_REGISTRY.isOperatorAllowed(
                    address(this),
                    msg.sender
                )
            ) {
                revert OperatorNotAllowed(msg.sender);
            }
        }
        _;
    }

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

// File: DefaultOperatorFilterer.sol

pragma solidity ^0.8.13;

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

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

// File: OrigamiClubNFTv3.sol

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

// File: https://github.com/chiru-labs/ERC721A/blob/main/contracts/IERC721A.sol

// ERC721A Contracts v4.2.2
// 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;

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId`
     * (inclusive) is transferred from `from` to `to`, as defined in the
     * [ERC2309](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: https://github.com/chiru-labs/ERC721A/blob/main/contracts/ERC721A.sol

// ERC721A Contracts v4.2.2
// 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 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 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 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 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`.
                )

                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: https://github.com/chiru-labs/ERC721A/blob/main/contracts/extensions/IERC721AQueryable.sol

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

pragma solidity ^0.8.4;

/**
 * @dev Interface of ERC721AQueryable.
 */
interface IERC721AQueryable is IERC721A {
    /**
     * Invalid query range (`start` >= `stop`).
     */
    error InvalidQueryRange();

    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *
     * - `addr = address(0)`
     * - `startTimestamp = 0`
     * - `burned = false`
     * - `extraData = 0`
     *
     * If the `tokenId` is burned:
     *
     * - `addr = <Address of owner before token was burned>`
     * - `startTimestamp = <Timestamp when token was burned>`
     * - `burned = true`
     * - `extraData = <Extra data when token was burned>`
     *
     * Otherwise:
     *
     * - `addr = <Address of owner>`
     * - `startTimestamp = <Timestamp of start of ownership>`
     * - `burned = false`
     * - `extraData = <Extra data at start of ownership>`
     */
    function explicitOwnershipOf(uint256 tokenId)
        external
        view
        returns (TokenOwnership memory);

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] memory tokenIds)
        external
        view
        returns (TokenOwnership[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start < stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) external view returns (uint256[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K collections should be fine).
     */
    function tokensOfOwner(address owner)
        external
        view
        returns (uint256[] memory);
}

// File: https://github.com/chiru-labs/ERC721A/blob/main/contracts/extensions/ERC721AQueryable.sol

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

pragma solidity ^0.8.4;

/**
 * @title ERC721AQueryable.
 *
 * @dev ERC721A subclass with convenience query functions.
 */
abstract contract ERC721AQueryable is ERC721A, IERC721AQueryable {
    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *
     * - `addr = address(0)`
     * - `startTimestamp = 0`
     * - `burned = false`
     * - `extraData = 0`
     *
     * If the `tokenId` is burned:
     *
     * - `addr = <Address of owner before token was burned>`
     * - `startTimestamp = <Timestamp when token was burned>`
     * - `burned = true`
     * - `extraData = <Extra data when token was burned>`
     *
     * Otherwise:
     *
     * - `addr = <Address of owner>`
     * - `startTimestamp = <Timestamp of start of ownership>`
     * - `burned = false`
     * - `extraData = <Extra data at start of ownership>`
     */
    function explicitOwnershipOf(uint256 tokenId)
        public
        view
        virtual
        override
        returns (TokenOwnership memory)
    {
        TokenOwnership memory ownership;
        if (tokenId < _startTokenId() || tokenId >= _nextTokenId()) {
            return ownership;
        }
        ownership = _ownershipAt(tokenId);
        if (ownership.burned) {
            return ownership;
        }
        return _ownershipOf(tokenId);
    }

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] calldata tokenIds)
        external
        view
        virtual
        override
        returns (TokenOwnership[] memory)
    {
        unchecked {
            uint256 tokenIdsLength = tokenIds.length;
            TokenOwnership[] memory ownerships = new TokenOwnership[](
                tokenIdsLength
            );
            for (uint256 i; i != tokenIdsLength; ++i) {
                ownerships[i] = explicitOwnershipOf(tokenIds[i]);
            }
            return ownerships;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start < stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) external view virtual override returns (uint256[] memory) {
        unchecked {
            if (start >= stop) revert InvalidQueryRange();
            uint256 tokenIdsIdx;
            uint256 stopLimit = _nextTokenId();
            // Set `start = max(start, _startTokenId())`.
            if (start < _startTokenId()) {
                start = _startTokenId();
            }
            // Set `stop = min(stop, stopLimit)`.
            if (stop > stopLimit) {
                stop = stopLimit;
            }
            uint256 tokenIdsMaxLength = balanceOf(owner);
            // Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`,
            // to cater for cases where `balanceOf(owner)` is too big.
            if (start < stop) {
                uint256 rangeLength = stop - start;
                if (rangeLength < tokenIdsMaxLength) {
                    tokenIdsMaxLength = rangeLength;
                }
            } else {
                tokenIdsMaxLength = 0;
            }
            uint256[] memory tokenIds = new uint256[](tokenIdsMaxLength);
            if (tokenIdsMaxLength == 0) {
                return tokenIds;
            }
            // We need to call `explicitOwnershipOf(start)`,
            // because the slot at `start` may not be initialized.
            TokenOwnership memory ownership = explicitOwnershipOf(start);
            address currOwnershipAddr;
            // If the starting slot exists (i.e. not burned), initialize `currOwnershipAddr`.
            // `ownership.address` will not be zero, as `start` is clamped to the valid token ID range.
            if (!ownership.burned) {
                currOwnershipAddr = ownership.addr;
            }
            for (
                uint256 i = start;
                i != stop && tokenIdsIdx != tokenIdsMaxLength;
                ++i
            ) {
                ownership = _ownershipAt(i);
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            // Downsize the array to fit.
            assembly {
                mstore(tokenIds, tokenIdsIdx)
            }
            return tokenIds;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K collections should be fine).
     */
    function tokensOfOwner(address owner)
        external
        view
        virtual
        override
        returns (uint256[] memory)
    {
        unchecked {
            uint256 tokenIdsIdx;
            address currOwnershipAddr;
            uint256 tokenIdsLength = balanceOf(owner);
            uint256[] memory tokenIds = new uint256[](tokenIdsLength);
            TokenOwnership memory ownership;
            for (
                uint256 i = _startTokenId();
                tokenIdsIdx != tokenIdsLength;
                ++i
            ) {
                ownership = _ownershipAt(i);
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            return tokenIds;
        }
    }
}

// File: https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol

pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OwnerUpdated(address indexed user, address indexed newOwner);

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnerUpdated(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function setOwner(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnerUpdated(msg.sender, newOwner);
    }
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol

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

pragma solidity ^0.8.0;

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

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

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/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: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol

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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721Receiver.sol

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

pragma solidity ^0.8.0;

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol

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

pragma solidity ^0.8.0;

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/ERC165.sol

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

pragma solidity ^0.8.0;

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/IERC721Metadata.sol

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

pragma solidity ^0.8.0;

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol

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

pragma solidity ^0.8.0;

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
        require(!_exists(tokenId), "ERC721: token already minted");

        unchecked {
            // Will not overflow unless all 2**256 token ids are minted to the same owner.
            // Given that tokens are minted one by one, it is impossible in practice that
            // this ever happens. Might change if we allow batch minting.
            // The ERC fails to describe this case.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;

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

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

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     * This is an internal function that does not check if the sender is authorized to operate on the token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

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

        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
        owner = ERC721.ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        unchecked {
            // Cannot overflow, as that would require more tokens to be burned/transferred
            // out than the owner initially received through minting and transferring in.
            _balances[owner] -= 1;
        }
        delete _owners[tokenId];

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        require(
            ERC721.ownerOf(tokenId) == from,
            "ERC721: transfer from incorrect owner"
        );

        // Clear approvals from the previous owner
        delete _tokenApprovals[tokenId];

        unchecked {
            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
            // `from`'s balance is the number of token held, which is at least one before the current
            // transfer.
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[from] -= 1;
            _balances[to] += 1;
        }
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

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

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

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

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

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

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

// File: contracts/OrigamiClub.sol

pragma solidity ^0.8.4;

contract OrigamiClub is
    ERC721A,
    ERC721AQueryable,
    DefaultOperatorFilterer,
    Owned
{
    uint256 public FIRST_MINT_PRICE = 0 ether;
    uint256 constant EXTRA_MINT_PRICE = 0.02 ether;
    uint256 constant MAX_SUPPLY_PLUS_ONE = 1001;
    uint256 constant MAX_PER_WALLET_PLUS_ONE = 5;
    uint256 RESERVED = 50;

    string tokenBaseUri =
        "ipfs://QmTViFpnui9XJLhnBiakbs3WUKXz2jaq4yttqJH117yxX1/hidden.json";

    bool public paused = true;

    mapping(address => uint256) private _freeMintedCount;
    mapping(address => uint256) private _totalMintedCount;

    constructor() ERC721A("OrigamiClub", "OGClub") Owned(msg.sender) {}

    // Rename mint function to optimize gas
    function mint_540(uint256 _quantity) external payable {
        unchecked {
            require(!paused, "MINTING PAUSED");
            require(
                _totalMintedCount[msg.sender] + _quantity <
                    MAX_PER_WALLET_PLUS_ONE,
                "MAX PER WALLET IS 5"
            );

            uint256 _totalSupply = totalSupply();

            require(
                _totalSupply + _quantity + RESERVED < MAX_SUPPLY_PLUS_ONE,
                "MAX SUPPLY REACHED"
            );

            uint256 payForCount = _quantity;
            uint256 payForFirstMint = 0;
            uint256 freeMintCount = _freeMintedCount[msg.sender];

            if (freeMintCount < 1) {
                if (_quantity > 1) {
                    payForCount = _quantity - 1;
                } else {
                    payForCount = 0;
                }
                payForFirstMint = 1;

                _freeMintedCount[msg.sender] = 1;
            }
            _totalMintedCount[msg.sender] += _quantity;

            require(
                msg.value >=
                    (payForCount *
                        EXTRA_MINT_PRICE +
                        payForFirstMint *
                        FIRST_MINT_PRICE),
                "INCORRECT ETH AMOUNT"
            );

            _mint(msg.sender, _quantity);
        }
    }

    // Set first mint price
    function setFirstMintPrice(uint256 _newPrice) public onlyOwner {
        FIRST_MINT_PRICE = _newPrice;
    }

    function freeMintedCount(address owner) external view returns (uint256) {
        return _freeMintedCount[owner];
    }

    function totalMintedCount(address owner) external view returns (uint256) {
        return _totalMintedCount[owner];
    }

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

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

    function setBaseURI(string calldata _newBaseUri) external onlyOwner {
        tokenBaseUri = _newBaseUri;
    }

    function flipSale() external onlyOwner {
        paused = !paused;
    }

    function collectReserves() external onlyOwner {
        require(RESERVED > 0, "RESERVES TAKEN");

        _mint(msg.sender, 50);
        RESERVED = 0;
    }

    function withdraw() external onlyOwner {
        require(payable(owner).send(address(this).balance), "UNSUCCESSFUL");
    }

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

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

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

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

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"FIRST_MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collectReserves","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flipSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"freeMintedCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"mint_540","outputs":[],"stateMutability":"payable","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":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseUri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setFirstMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"totalMintedCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260006009556032600a55604051806080016040528060418152602001620041fa60419139600b90805190602001906200003f929190620003da565b506001600c60006101000a81548160ff0219169083151502179055503480156200006857600080fd5b5033733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600b81526020017f4f726967616d69436c75620000000000000000000000000000000000000000008152506040518060400160405280600681526020017f4f47436c75620000000000000000000000000000000000000000000000000000815250816002908051906020019062000105929190620003da565b5080600390805190602001906200011e929190620003da565b506200012f620003d160201b60201c565b600081905550505060006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156200032c578015620001f2576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b8152600401620001b8929190620004cf565b600060405180830381600087803b158015620001d357600080fd5b505af1158015620001e8573d6000803e3d6000fd5b505050506200032b565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620002ac576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b815260040162000272929190620004cf565b600060405180830381600087803b1580156200028d57600080fd5b505af1158015620002a2573d6000803e3d6000fd5b505050506200032a565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b8152600401620002f59190620004fc565b600060405180830381600087803b1580156200031057600080fd5b505af115801562000325573d6000803e3d6000fd5b505050505b5b5b505080600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7660405160405180910390a3506200057d565b60006001905090565b828054620003e89062000548565b90600052602060002090601f0160209004810192826200040c576000855562000458565b82601f106200042757805160ff191683800117855562000458565b8280016001018555821562000458579182015b82811115620004575782518255916020019190600101906200043a565b5b5090506200046791906200046b565b5090565b5b80821115620004865760008160009055506001016200046c565b5090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620004b7826200048a565b9050919050565b620004c981620004aa565b82525050565b6000604082019050620004e66000830185620004be565b620004f56020830184620004be565b9392505050565b6000602082019050620005136000830184620004be565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200056157607f821691505b60208210810362000577576200057662000519565b5b50919050565b613c6d806200058d6000396000f3fe6080604052600436106101cb5760003560e01c80636352211e116100f75780639813323511610095578063bfc28c0a11610064578063bfc28c0a14610663578063c23dc68f146106a0578063c87b56dd146106dd578063e985e9c51461071a576101cb565b8063981332351461059757806399a2557a146105d4578063a22cb46514610611578063b88d4fde1461063a576101cb565b80638462151c116100d15780638462151c146104d95780638da5cb5b1461051657806392ee40251461054157806395d89b411461056c576101cb565b80636352211e1461044857806370a08231146104855780637ba5e621146104c2576101cb565b806318160ddd1161016f57806342842e0e1161013e57806342842e0e1461038e57806355f804b3146103b75780635bbb2177146103e05780635c975abb1461041d576101cb565b806318160ddd146102fa5780632052e89d1461032557806323b872dd1461034e5780633ccfd60b14610377576101cb565b806306fdde03116101ab57806306fdde0314610240578063081812fc1461026b578063095ea7b3146102a857806313af4035146102d1576101cb565b80619d1c146101d057806301ffc9a7146101ec578063029877b614610229575b600080fd5b6101ea60048036038101906101e59190612d15565b610757565b005b3480156101f857600080fd5b50610213600480360381019061020e9190612d9a565b6109e7565b6040516102209190612de2565b60405180910390f35b34801561023557600080fd5b5061023e610a79565b005b34801561024c57600080fd5b50610255610b63565b6040516102629190612e96565b60405180910390f35b34801561027757600080fd5b50610292600480360381019061028d9190612d15565b610bf5565b60405161029f9190612ef9565b60405180910390f35b3480156102b457600080fd5b506102cf60048036038101906102ca9190612f40565b610c74565b005b3480156102dd57600080fd5b506102f860048036038101906102f39190612f80565b610d7e565b005b34801561030657600080fd5b5061030f610eac565b60405161031c9190612fbc565b60405180910390f35b34801561033157600080fd5b5061034c60048036038101906103479190612d15565b610ec3565b005b34801561035a57600080fd5b5061037560048036038101906103709190612fd7565b610f5d565b005b34801561038357600080fd5b5061038c6110ad565b005b34801561039a57600080fd5b506103b560048036038101906103b09190612fd7565b6111d5565b005b3480156103c357600080fd5b506103de60048036038101906103d9919061308f565b611325565b005b3480156103ec57600080fd5b5061040760048036038101906104029190613132565b6113cb565b60405161041491906132e2565b60405180910390f35b34801561042957600080fd5b5061043261148e565b60405161043f9190612de2565b60405180910390f35b34801561045457600080fd5b5061046f600480360381019061046a9190612d15565b6114a1565b60405161047c9190612ef9565b60405180910390f35b34801561049157600080fd5b506104ac60048036038101906104a79190612f80565b6114b3565b6040516104b99190612fbc565b60405180910390f35b3480156104ce57600080fd5b506104d761156b565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190612f80565b611627565b60405161050d91906133c2565b60405180910390f35b34801561052257600080fd5b5061052b61176a565b6040516105389190612ef9565b60405180910390f35b34801561054d57600080fd5b50610556611790565b6040516105639190612fbc565b60405180910390f35b34801561057857600080fd5b50610581611796565b60405161058e9190612e96565b60405180910390f35b3480156105a357600080fd5b506105be60048036038101906105b99190612f80565b611828565b6040516105cb9190612fbc565b60405180910390f35b3480156105e057600080fd5b506105fb60048036038101906105f691906133e4565b611871565b60405161060891906133c2565b60405180910390f35b34801561061d57600080fd5b5061063860048036038101906106339190613463565b611a7d565b005b34801561064657600080fd5b50610661600480360381019061065c91906135d3565b611b87565b005b34801561066f57600080fd5b5061068a60048036038101906106859190612f80565b611cda565b6040516106979190612fbc565b60405180910390f35b3480156106ac57600080fd5b506106c760048036038101906106c29190612d15565b611d23565b6040516106d491906136ab565b60405180910390f35b3480156106e957600080fd5b5061070460048036038101906106ff9190612d15565b611d8d565b6040516107119190612e96565b60405180910390f35b34801561072657600080fd5b50610741600480360381019061073c91906136c6565b611e2b565b60405161074e9190612de2565b60405180910390f35b600c60009054906101000a900460ff16156107a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161079e90613752565b60405180910390fd5b600581600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054011061082b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610822906137be565b60405180910390fd5b6000610835610eac565b90506103e9600a548383010110610881576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108789061382a565b60405180910390fd5b6000829050600080600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060018110156109375760018511156108e8576001850392506108ed565b600092505b600191506001600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b84600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550600954820266470de4df8200008402013410156109d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109cd90613896565b60405180910390fd5b6109e03386611ebf565b5050505050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a4257506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a725750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0090613902565b60405180910390fd5b6000600a5411610b4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b459061396e565b60405180910390fd5b610b59336032611ebf565b6000600a81905550565b606060028054610b72906139bd565b80601f0160208091040260200160405190810160405280929190818152602001828054610b9e906139bd565b8015610beb5780601f10610bc057610100808354040283529160200191610beb565b820191906000526020600020905b815481529060010190602001808311610bce57829003601f168201915b5050505050905090565b6000610c008261207a565b610c36576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610d6f576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401610cec9291906139ee565b602060405180830381865afa158015610d09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2d9190613a2c565b610d6e57806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610d659190612ef9565b60405180910390fd5b5b610d7983836120d9565b505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0590613902565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7660405160405180910390a350565b6000610eb661221d565b6001546000540303905090565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4a90613902565b60405180910390fd5b8060098190555050565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111561109b573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610fcf57610fca848484612226565b6110a7565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016110189291906139ee565b602060405180830381865afa158015611035573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110599190613a2c565b61109a57336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016110919190612ef9565b60405180910390fd5b5b6110a6848484612226565b5b50505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461113d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113490613902565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f193505050506111d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ca90613aa5565b60405180910390fd5b565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611313573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361124757611242848484612548565b61131f565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016112909291906139ee565b602060405180830381865afa1580156112ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d19190613a2c565b61131257336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016113099190612ef9565b60405180910390fd5b5b61131e848484612548565b5b50505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ac90613902565b60405180910390fd5b8181600b91906113c6929190612bd9565b505050565b6060600083839050905060008167ffffffffffffffff8111156113f1576113f06134a8565b5b60405190808252806020026020018201604052801561142a57816020015b611417612c5f565b81526020019060019003908161140f5790505b50905060005b8281146114825761145986868381811061144d5761144c613ac5565b5b90506020020135611d23565b82828151811061146c5761146b613ac5565b5b6020026020010181905250806001019050611430565b50809250505092915050565b600c60009054906101000a900460ff1681565b60006114ac82612568565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361151a576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f290613902565b60405180910390fd5b600c60009054906101000a900460ff1615600c60006101000a81548160ff021916908315150217905550565b60606000806000611637856114b3565b905060008167ffffffffffffffff811115611655576116546134a8565b5b6040519080825280602002602001820160405280156116835781602001602082028036833780820191505090505b50905061168e612c5f565b600061169861221d565b90505b83861461175c576116ab81612634565b9150816040015161175157600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16146116f657816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611750578083878060010198508151811061174357611742613ac5565b5b6020026020010181815250505b5b80600101905061169b565b508195505050505050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60095481565b6060600380546117a5906139bd565b80601f01602080910402602001604051908101604052809291908181526020018280546117d1906139bd565b801561181e5780601f106117f35761010080835404028352916020019161181e565b820191906000526020600020905b81548152906001019060200180831161180157829003601f168201915b5050505050905090565b6000600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60608183106118ac576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806118b761265f565b90506118c161221d565b8510156118d3576118d061221d565b94505b808411156118df578093505b60006118ea876114b3565b90508486101561190d576000868603905081811015611907578091505b50611912565b600090505b60008167ffffffffffffffff81111561192e5761192d6134a8565b5b60405190808252806020026020018201604052801561195c5781602001602082028036833780820191505090505b509050600082036119735780945050505050611a76565b600061197e88611d23565b90506000816040015161199357816000015190505b60008990505b8881141580156119a95750848714155b15611a68576119b781612634565b92508260400151611a5d57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611a0257826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611a5c5780848880600101995081518110611a4f57611a4e613ac5565b5b6020026020010181815250505b5b806001019050611999565b508583528296505050505050505b9392505050565b8160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611b78576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611af59291906139ee565b602060405180830381865afa158015611b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b369190613a2c565b611b7757806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611b6e9190612ef9565b60405180910390fd5b5b611b828383612668565b505050565b8360006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611cc6573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611bfa57611bf585858585612773565b611cd3565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611c439291906139ee565b602060405180830381865afa158015611c60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c849190613a2c565b611cc557336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611cbc9190612ef9565b60405180910390fd5b5b611cd285858585612773565b5b5050505050565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611d2b612c5f565b611d33612c5f565b611d3b61221d565b831080611d4f5750611d4b61265f565b8310155b15611d5d5780915050611d88565b611d6683612634565b9050806040015115611d7b5780915050611d88565b611d84836127e6565b9150505b919050565b6060611d988261207a565b611dce576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611dd8612806565b90506000815103611df85760405180602001604052806000815250611e23565b80611e0284612898565b604051602001611e13929190613b30565b6040516020818303038152906040525b915050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008054905060008203611eff576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f0c60008483856128e8565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611f8383611f7460008660006128ee565b611f7d85612916565b17612926565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461202457808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050611fe9565b506000820361205f576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060008190555050506120756000848385612951565b505050565b60008161208561221d565b11158015612094575060005482105b80156120d2575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60006120e4826114a1565b90508073ffffffffffffffffffffffffffffffffffffffff16612105612957565b73ffffffffffffffffffffffffffffffffffffffff1614612168576121318161212c612957565b611e2b565b612167576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b600061223182612568565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612298576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806122a48461295f565b915091506122ba81876122b5612957565b612986565b612306576122cf866122ca612957565b611e2b565b612305576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361236c576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61237986868660016128e8565b801561238457600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055506124528561242e8888876128ee565b7c020000000000000000000000000000000000000000000000000000000017612926565b600460008681526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008416036124d857600060018501905060006004600083815260200190815260200160002054036124d65760005481146124d5578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46125408686866001612951565b505050505050565b61256383838360405180602001604052806000815250611b87565b505050565b6000808290508061257761221d565b116125fd576000548110156125fc5760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036125fa575b600081036125f05760046000836001900393508381526020019081526020016000205490506125c6565b809250505061262f565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b61263c612c5f565b61265860046000848152602001908152602001600020546129ca565b9050919050565b60008054905090565b8060076000612675612957565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612722612957565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516127679190612de2565b60405180910390a35050565b61277e848484610f5d565b60008373ffffffffffffffffffffffffffffffffffffffff163b146127e0576127a984848484612a80565b6127df576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6127ee612c5f565b6127ff6127fa83612568565b6129ca565b9050919050565b6060600b8054612815906139bd565b80601f0160208091040260200160405190810160405280929190818152602001828054612841906139bd565b801561288e5780601f106128635761010080835404028352916020019161288e565b820191906000526020600020905b81548152906001019060200180831161287157829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b6001156128d357600184039350600a81066030018453600a81049050806128b1575b50828103602084039350808452505050919050565b50505050565b60008060e883901c905060e8612905868684612bd0565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600033905090565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b6129d2612c5f565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612aa6612957565b8786866040518563ffffffff1660e01b8152600401612ac89493929190613ba9565b6020604051808303816000875af1925050508015612b0457506040513d601f19601f82011682018060405250810190612b019190613c0a565b60015b612b7d573d8060008114612b34576040519150601f19603f3d011682016040523d82523d6000602084013e612b39565b606091505b506000815103612b75576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60009392505050565b828054612be5906139bd565b90600052602060002090601f016020900481019282612c075760008555612c4e565b82601f10612c2057803560ff1916838001178555612c4e565b82800160010185558215612c4e579182015b82811115612c4d578235825591602001919060010190612c32565b5b509050612c5b9190612cae565b5090565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b5b80821115612cc7576000816000905550600101612caf565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b612cf281612cdf565b8114612cfd57600080fd5b50565b600081359050612d0f81612ce9565b92915050565b600060208284031215612d2b57612d2a612cd5565b5b6000612d3984828501612d00565b91505092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612d7781612d42565b8114612d8257600080fd5b50565b600081359050612d9481612d6e565b92915050565b600060208284031215612db057612daf612cd5565b5b6000612dbe84828501612d85565b91505092915050565b60008115159050919050565b612ddc81612dc7565b82525050565b6000602082019050612df76000830184612dd3565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612e37578082015181840152602081019050612e1c565b83811115612e46576000848401525b50505050565b6000601f19601f8301169050919050565b6000612e6882612dfd565b612e728185612e08565b9350612e82818560208601612e19565b612e8b81612e4c565b840191505092915050565b60006020820190508181036000830152612eb08184612e5d565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612ee382612eb8565b9050919050565b612ef381612ed8565b82525050565b6000602082019050612f0e6000830184612eea565b92915050565b612f1d81612ed8565b8114612f2857600080fd5b50565b600081359050612f3a81612f14565b92915050565b60008060408385031215612f5757612f56612cd5565b5b6000612f6585828601612f2b565b9250506020612f7685828601612d00565b9150509250929050565b600060208284031215612f9657612f95612cd5565b5b6000612fa484828501612f2b565b91505092915050565b612fb681612cdf565b82525050565b6000602082019050612fd16000830184612fad565b92915050565b600080600060608486031215612ff057612fef612cd5565b5b6000612ffe86828701612f2b565b935050602061300f86828701612f2b565b925050604061302086828701612d00565b9150509250925092565b600080fd5b600080fd5b600080fd5b60008083601f84011261304f5761304e61302a565b5b8235905067ffffffffffffffff81111561306c5761306b61302f565b5b60208301915083600182028301111561308857613087613034565b5b9250929050565b600080602083850312156130a6576130a5612cd5565b5b600083013567ffffffffffffffff8111156130c4576130c3612cda565b5b6130d085828601613039565b92509250509250929050565b60008083601f8401126130f2576130f161302a565b5b8235905067ffffffffffffffff81111561310f5761310e61302f565b5b60208301915083602082028301111561312b5761312a613034565b5b9250929050565b6000806020838503121561314957613148612cd5565b5b600083013567ffffffffffffffff81111561316757613166612cda565b5b613173858286016130dc565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6131b481612ed8565b82525050565b600067ffffffffffffffff82169050919050565b6131d7816131ba565b82525050565b6131e681612dc7565b82525050565b600062ffffff82169050919050565b613204816131ec565b82525050565b60808201600082015161322060008501826131ab565b50602082015161323360208501826131ce565b50604082015161324660408501826131dd565b50606082015161325960608501826131fb565b50505050565b600061326b838361320a565b60808301905092915050565b6000602082019050919050565b600061328f8261317f565b613299818561318a565b93506132a48361319b565b8060005b838110156132d55781516132bc888261325f565b97506132c783613277565b9250506001810190506132a8565b5085935050505092915050565b600060208201905081810360008301526132fc8184613284565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61333981612cdf565b82525050565b600061334b8383613330565b60208301905092915050565b6000602082019050919050565b600061336f82613304565b613379818561330f565b935061338483613320565b8060005b838110156133b557815161339c888261333f565b97506133a783613357565b925050600181019050613388565b5085935050505092915050565b600060208201905081810360008301526133dc8184613364565b905092915050565b6000806000606084860312156133fd576133fc612cd5565b5b600061340b86828701612f2b565b935050602061341c86828701612d00565b925050604061342d86828701612d00565b9150509250925092565b61344081612dc7565b811461344b57600080fd5b50565b60008135905061345d81613437565b92915050565b6000806040838503121561347a57613479612cd5565b5b600061348885828601612f2b565b92505060206134998582860161344e565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6134e082612e4c565b810181811067ffffffffffffffff821117156134ff576134fe6134a8565b5b80604052505050565b6000613512612ccb565b905061351e82826134d7565b919050565b600067ffffffffffffffff82111561353e5761353d6134a8565b5b61354782612e4c565b9050602081019050919050565b82818337600083830152505050565b600061357661357184613523565b613508565b905082815260208101848484011115613592576135916134a3565b5b61359d848285613554565b509392505050565b600082601f8301126135ba576135b961302a565b5b81356135ca848260208601613563565b91505092915050565b600080600080608085870312156135ed576135ec612cd5565b5b60006135fb87828801612f2b565b945050602061360c87828801612f2b565b935050604061361d87828801612d00565b925050606085013567ffffffffffffffff81111561363e5761363d612cda565b5b61364a878288016135a5565b91505092959194509250565b60808201600082015161366c60008501826131ab565b50602082015161367f60208501826131ce565b50604082015161369260408501826131dd565b5060608201516136a560608501826131fb565b50505050565b60006080820190506136c06000830184613656565b92915050565b600080604083850312156136dd576136dc612cd5565b5b60006136eb85828601612f2b565b92505060206136fc85828601612f2b565b9150509250929050565b7f4d494e54494e4720504155534544000000000000000000000000000000000000600082015250565b600061373c600e83612e08565b915061374782613706565b602082019050919050565b6000602082019050818103600083015261376b8161372f565b9050919050565b7f4d4158205045522057414c4c4554204953203500000000000000000000000000600082015250565b60006137a8601383612e08565b91506137b382613772565b602082019050919050565b600060208201905081810360008301526137d78161379b565b9050919050565b7f4d415820535550504c5920524541434845440000000000000000000000000000600082015250565b6000613814601283612e08565b915061381f826137de565b602082019050919050565b6000602082019050818103600083015261384381613807565b9050919050565b7f494e434f52524543542045544820414d4f554e54000000000000000000000000600082015250565b6000613880601483612e08565b915061388b8261384a565b602082019050919050565b600060208201905081810360008301526138af81613873565b9050919050565b7f554e415554484f52495a45440000000000000000000000000000000000000000600082015250565b60006138ec600c83612e08565b91506138f7826138b6565b602082019050919050565b6000602082019050818103600083015261391b816138df565b9050919050565b7f52455345525645532054414b454e000000000000000000000000000000000000600082015250565b6000613958600e83612e08565b915061396382613922565b602082019050919050565b600060208201905081810360008301526139878161394b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806139d557607f821691505b6020821081036139e8576139e761398e565b5b50919050565b6000604082019050613a036000830185612eea565b613a106020830184612eea565b9392505050565b600081519050613a2681613437565b92915050565b600060208284031215613a4257613a41612cd5565b5b6000613a5084828501613a17565b91505092915050565b7f554e5355434345535346554c0000000000000000000000000000000000000000600082015250565b6000613a8f600c83612e08565b9150613a9a82613a59565b602082019050919050565b60006020820190508181036000830152613abe81613a82565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081905092915050565b6000613b0a82612dfd565b613b148185613af4565b9350613b24818560208601612e19565b80840191505092915050565b6000613b3c8285613aff565b9150613b488284613aff565b91508190509392505050565b600081519050919050565b600082825260208201905092915050565b6000613b7b82613b54565b613b858185613b5f565b9350613b95818560208601612e19565b613b9e81612e4c565b840191505092915050565b6000608082019050613bbe6000830187612eea565b613bcb6020830186612eea565b613bd86040830185612fad565b8181036060830152613bea8184613b70565b905095945050505050565b600081519050613c0481612d6e565b92915050565b600060208284031215613c2057613c1f612cd5565b5b6000613c2e84828501613bf5565b9150509291505056fea2646970667358221220799a4bd362a6517405a48438040b7a459e0eeae597a10f6f01dd08f0adbac7ee64736f6c634300080d0033697066733a2f2f516d54566946706e756939584a4c686e4269616b62733357554b587a326a617134797474714a48313137797858312f68696464656e2e6a736f6e

Deployed Bytecode

0x6080604052600436106101cb5760003560e01c80636352211e116100f75780639813323511610095578063bfc28c0a11610064578063bfc28c0a14610663578063c23dc68f146106a0578063c87b56dd146106dd578063e985e9c51461071a576101cb565b8063981332351461059757806399a2557a146105d4578063a22cb46514610611578063b88d4fde1461063a576101cb565b80638462151c116100d15780638462151c146104d95780638da5cb5b1461051657806392ee40251461054157806395d89b411461056c576101cb565b80636352211e1461044857806370a08231146104855780637ba5e621146104c2576101cb565b806318160ddd1161016f57806342842e0e1161013e57806342842e0e1461038e57806355f804b3146103b75780635bbb2177146103e05780635c975abb1461041d576101cb565b806318160ddd146102fa5780632052e89d1461032557806323b872dd1461034e5780633ccfd60b14610377576101cb565b806306fdde03116101ab57806306fdde0314610240578063081812fc1461026b578063095ea7b3146102a857806313af4035146102d1576101cb565b80619d1c146101d057806301ffc9a7146101ec578063029877b614610229575b600080fd5b6101ea60048036038101906101e59190612d15565b610757565b005b3480156101f857600080fd5b50610213600480360381019061020e9190612d9a565b6109e7565b6040516102209190612de2565b60405180910390f35b34801561023557600080fd5b5061023e610a79565b005b34801561024c57600080fd5b50610255610b63565b6040516102629190612e96565b60405180910390f35b34801561027757600080fd5b50610292600480360381019061028d9190612d15565b610bf5565b60405161029f9190612ef9565b60405180910390f35b3480156102b457600080fd5b506102cf60048036038101906102ca9190612f40565b610c74565b005b3480156102dd57600080fd5b506102f860048036038101906102f39190612f80565b610d7e565b005b34801561030657600080fd5b5061030f610eac565b60405161031c9190612fbc565b60405180910390f35b34801561033157600080fd5b5061034c60048036038101906103479190612d15565b610ec3565b005b34801561035a57600080fd5b5061037560048036038101906103709190612fd7565b610f5d565b005b34801561038357600080fd5b5061038c6110ad565b005b34801561039a57600080fd5b506103b560048036038101906103b09190612fd7565b6111d5565b005b3480156103c357600080fd5b506103de60048036038101906103d9919061308f565b611325565b005b3480156103ec57600080fd5b5061040760048036038101906104029190613132565b6113cb565b60405161041491906132e2565b60405180910390f35b34801561042957600080fd5b5061043261148e565b60405161043f9190612de2565b60405180910390f35b34801561045457600080fd5b5061046f600480360381019061046a9190612d15565b6114a1565b60405161047c9190612ef9565b60405180910390f35b34801561049157600080fd5b506104ac60048036038101906104a79190612f80565b6114b3565b6040516104b99190612fbc565b60405180910390f35b3480156104ce57600080fd5b506104d761156b565b005b3480156104e557600080fd5b5061050060048036038101906104fb9190612f80565b611627565b60405161050d91906133c2565b60405180910390f35b34801561052257600080fd5b5061052b61176a565b6040516105389190612ef9565b60405180910390f35b34801561054d57600080fd5b50610556611790565b6040516105639190612fbc565b60405180910390f35b34801561057857600080fd5b50610581611796565b60405161058e9190612e96565b60405180910390f35b3480156105a357600080fd5b506105be60048036038101906105b99190612f80565b611828565b6040516105cb9190612fbc565b60405180910390f35b3480156105e057600080fd5b506105fb60048036038101906105f691906133e4565b611871565b60405161060891906133c2565b60405180910390f35b34801561061d57600080fd5b5061063860048036038101906106339190613463565b611a7d565b005b34801561064657600080fd5b50610661600480360381019061065c91906135d3565b611b87565b005b34801561066f57600080fd5b5061068a60048036038101906106859190612f80565b611cda565b6040516106979190612fbc565b60405180910390f35b3480156106ac57600080fd5b506106c760048036038101906106c29190612d15565b611d23565b6040516106d491906136ab565b60405180910390f35b3480156106e957600080fd5b5061070460048036038101906106ff9190612d15565b611d8d565b6040516107119190612e96565b60405180910390f35b34801561072657600080fd5b50610741600480360381019061073c91906136c6565b611e2b565b60405161074e9190612de2565b60405180910390f35b600c60009054906101000a900460ff16156107a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161079e90613752565b60405180910390fd5b600581600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054011061082b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610822906137be565b60405180910390fd5b6000610835610eac565b90506103e9600a548383010110610881576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108789061382a565b60405180910390fd5b6000829050600080600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060018110156109375760018511156108e8576001850392506108ed565b600092505b600191506001600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b84600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550600954820266470de4df8200008402013410156109d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109cd90613896565b60405180910390fd5b6109e03386611ebf565b5050505050565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a4257506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610a725750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0090613902565b60405180910390fd5b6000600a5411610b4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b459061396e565b60405180910390fd5b610b59336032611ebf565b6000600a81905550565b606060028054610b72906139bd565b80601f0160208091040260200160405190810160405280929190818152602001828054610b9e906139bd565b8015610beb5780601f10610bc057610100808354040283529160200191610beb565b820191906000526020600020905b815481529060010190602001808311610bce57829003601f168201915b5050505050905090565b6000610c008261207a565b610c36576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610d6f576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401610cec9291906139ee565b602060405180830381865afa158015610d09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2d9190613a2c565b610d6e57806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610d659190612ef9565b60405180910390fd5b5b610d7983836120d9565b505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0590613902565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7660405160405180910390a350565b6000610eb661221d565b6001546000540303905090565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4a90613902565b60405180910390fd5b8060098190555050565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111561109b573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610fcf57610fca848484612226565b6110a7565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016110189291906139ee565b602060405180830381865afa158015611035573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110599190613a2c565b61109a57336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016110919190612ef9565b60405180910390fd5b5b6110a6848484612226565b5b50505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461113d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113490613902565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f193505050506111d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ca90613aa5565b60405180910390fd5b565b8260006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611313573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361124757611242848484612548565b61131f565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016112909291906139ee565b602060405180830381865afa1580156112ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d19190613a2c565b61131257336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016113099190612ef9565b60405180910390fd5b5b61131e848484612548565b5b50505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ac90613902565b60405180910390fd5b8181600b91906113c6929190612bd9565b505050565b6060600083839050905060008167ffffffffffffffff8111156113f1576113f06134a8565b5b60405190808252806020026020018201604052801561142a57816020015b611417612c5f565b81526020019060019003908161140f5790505b50905060005b8281146114825761145986868381811061144d5761144c613ac5565b5b90506020020135611d23565b82828151811061146c5761146b613ac5565b5b6020026020010181905250806001019050611430565b50809250505092915050565b600c60009054906101000a900460ff1681565b60006114ac82612568565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361151a576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115f290613902565b60405180910390fd5b600c60009054906101000a900460ff1615600c60006101000a81548160ff021916908315150217905550565b60606000806000611637856114b3565b905060008167ffffffffffffffff811115611655576116546134a8565b5b6040519080825280602002602001820160405280156116835781602001602082028036833780820191505090505b50905061168e612c5f565b600061169861221d565b90505b83861461175c576116ab81612634565b9150816040015161175157600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff16146116f657816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611750578083878060010198508151811061174357611742613ac5565b5b6020026020010181815250505b5b80600101905061169b565b508195505050505050919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60095481565b6060600380546117a5906139bd565b80601f01602080910402602001604051908101604052809291908181526020018280546117d1906139bd565b801561181e5780601f106117f35761010080835404028352916020019161181e565b820191906000526020600020905b81548152906001019060200180831161180157829003601f168201915b5050505050905090565b6000600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60608183106118ac576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806118b761265f565b90506118c161221d565b8510156118d3576118d061221d565b94505b808411156118df578093505b60006118ea876114b3565b90508486101561190d576000868603905081811015611907578091505b50611912565b600090505b60008167ffffffffffffffff81111561192e5761192d6134a8565b5b60405190808252806020026020018201604052801561195c5781602001602082028036833780820191505090505b509050600082036119735780945050505050611a76565b600061197e88611d23565b90506000816040015161199357816000015190505b60008990505b8881141580156119a95750848714155b15611a68576119b781612634565b92508260400151611a5d57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611a0257826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611a5c5780848880600101995081518110611a4f57611a4e613ac5565b5b6020026020010181815250505b5b806001019050611999565b508583528296505050505050505b9392505050565b8160006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611b78576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611af59291906139ee565b602060405180830381865afa158015611b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b369190613a2c565b611b7757806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611b6e9190612ef9565b60405180910390fd5b5b611b828383612668565b505050565b8360006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611cc6573373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611bfa57611bf585858585612773565b611cd3565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611c439291906139ee565b602060405180830381865afa158015611c60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c849190613a2c565b611cc557336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611cbc9190612ef9565b60405180910390fd5b5b611cd285858585612773565b5b5050505050565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611d2b612c5f565b611d33612c5f565b611d3b61221d565b831080611d4f5750611d4b61265f565b8310155b15611d5d5780915050611d88565b611d6683612634565b9050806040015115611d7b5780915050611d88565b611d84836127e6565b9150505b919050565b6060611d988261207a565b611dce576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611dd8612806565b90506000815103611df85760405180602001604052806000815250611e23565b80611e0284612898565b604051602001611e13929190613b30565b6040516020818303038152906040525b915050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008054905060008203611eff576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f0c60008483856128e8565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611f8383611f7460008660006128ee565b611f7d85612916565b17612926565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b81811461202457808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050611fe9565b506000820361205f576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060008190555050506120756000848385612951565b505050565b60008161208561221d565b11158015612094575060005482105b80156120d2575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60006120e4826114a1565b90508073ffffffffffffffffffffffffffffffffffffffff16612105612957565b73ffffffffffffffffffffffffffffffffffffffff1614612168576121318161212c612957565b611e2b565b612167576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60006001905090565b600061223182612568565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612298576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806122a48461295f565b915091506122ba81876122b5612957565b612986565b612306576122cf866122ca612957565b611e2b565b612305576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361236c576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61237986868660016128e8565b801561238457600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055506124528561242e8888876128ee565b7c020000000000000000000000000000000000000000000000000000000017612926565b600460008681526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008416036124d857600060018501905060006004600083815260200190815260200160002054036124d65760005481146124d5578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46125408686866001612951565b505050505050565b61256383838360405180602001604052806000815250611b87565b505050565b6000808290508061257761221d565b116125fd576000548110156125fc5760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036125fa575b600081036125f05760046000836001900393508381526020019081526020016000205490506125c6565b809250505061262f565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b61263c612c5f565b61265860046000848152602001908152602001600020546129ca565b9050919050565b60008054905090565b8060076000612675612957565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612722612957565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516127679190612de2565b60405180910390a35050565b61277e848484610f5d565b60008373ffffffffffffffffffffffffffffffffffffffff163b146127e0576127a984848484612a80565b6127df576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6127ee612c5f565b6127ff6127fa83612568565b6129ca565b9050919050565b6060600b8054612815906139bd565b80601f0160208091040260200160405190810160405280929190818152602001828054612841906139bd565b801561288e5780601f106128635761010080835404028352916020019161288e565b820191906000526020600020905b81548152906001019060200180831161287157829003601f168201915b5050505050905090565b606060a060405101806040526020810391506000825281835b6001156128d357600184039350600a81066030018453600a81049050806128b1575b50828103602084039350808452505050919050565b50505050565b60008060e883901c905060e8612905868684612bd0565b62ffffff16901b9150509392505050565b60006001821460e11b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b600033905090565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b6129d2612c5f565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612aa6612957565b8786866040518563ffffffff1660e01b8152600401612ac89493929190613ba9565b6020604051808303816000875af1925050508015612b0457506040513d601f19601f82011682018060405250810190612b019190613c0a565b60015b612b7d573d8060008114612b34576040519150601f19603f3d011682016040523d82523d6000602084013e612b39565b606091505b506000815103612b75576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b60009392505050565b828054612be5906139bd565b90600052602060002090601f016020900481019282612c075760008555612c4e565b82601f10612c2057803560ff1916838001178555612c4e565b82800160010185558215612c4e579182015b82811115612c4d578235825591602001919060010190612c32565b5b509050612c5b9190612cae565b5090565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b5b80821115612cc7576000816000905550600101612caf565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b612cf281612cdf565b8114612cfd57600080fd5b50565b600081359050612d0f81612ce9565b92915050565b600060208284031215612d2b57612d2a612cd5565b5b6000612d3984828501612d00565b91505092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612d7781612d42565b8114612d8257600080fd5b50565b600081359050612d9481612d6e565b92915050565b600060208284031215612db057612daf612cd5565b5b6000612dbe84828501612d85565b91505092915050565b60008115159050919050565b612ddc81612dc7565b82525050565b6000602082019050612df76000830184612dd3565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612e37578082015181840152602081019050612e1c565b83811115612e46576000848401525b50505050565b6000601f19601f8301169050919050565b6000612e6882612dfd565b612e728185612e08565b9350612e82818560208601612e19565b612e8b81612e4c565b840191505092915050565b60006020820190508181036000830152612eb08184612e5d565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612ee382612eb8565b9050919050565b612ef381612ed8565b82525050565b6000602082019050612f0e6000830184612eea565b92915050565b612f1d81612ed8565b8114612f2857600080fd5b50565b600081359050612f3a81612f14565b92915050565b60008060408385031215612f5757612f56612cd5565b5b6000612f6585828601612f2b565b9250506020612f7685828601612d00565b9150509250929050565b600060208284031215612f9657612f95612cd5565b5b6000612fa484828501612f2b565b91505092915050565b612fb681612cdf565b82525050565b6000602082019050612fd16000830184612fad565b92915050565b600080600060608486031215612ff057612fef612cd5565b5b6000612ffe86828701612f2b565b935050602061300f86828701612f2b565b925050604061302086828701612d00565b9150509250925092565b600080fd5b600080fd5b600080fd5b60008083601f84011261304f5761304e61302a565b5b8235905067ffffffffffffffff81111561306c5761306b61302f565b5b60208301915083600182028301111561308857613087613034565b5b9250929050565b600080602083850312156130a6576130a5612cd5565b5b600083013567ffffffffffffffff8111156130c4576130c3612cda565b5b6130d085828601613039565b92509250509250929050565b60008083601f8401126130f2576130f161302a565b5b8235905067ffffffffffffffff81111561310f5761310e61302f565b5b60208301915083602082028301111561312b5761312a613034565b5b9250929050565b6000806020838503121561314957613148612cd5565b5b600083013567ffffffffffffffff81111561316757613166612cda565b5b613173858286016130dc565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6131b481612ed8565b82525050565b600067ffffffffffffffff82169050919050565b6131d7816131ba565b82525050565b6131e681612dc7565b82525050565b600062ffffff82169050919050565b613204816131ec565b82525050565b60808201600082015161322060008501826131ab565b50602082015161323360208501826131ce565b50604082015161324660408501826131dd565b50606082015161325960608501826131fb565b50505050565b600061326b838361320a565b60808301905092915050565b6000602082019050919050565b600061328f8261317f565b613299818561318a565b93506132a48361319b565b8060005b838110156132d55781516132bc888261325f565b97506132c783613277565b9250506001810190506132a8565b5085935050505092915050565b600060208201905081810360008301526132fc8184613284565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61333981612cdf565b82525050565b600061334b8383613330565b60208301905092915050565b6000602082019050919050565b600061336f82613304565b613379818561330f565b935061338483613320565b8060005b838110156133b557815161339c888261333f565b97506133a783613357565b925050600181019050613388565b5085935050505092915050565b600060208201905081810360008301526133dc8184613364565b905092915050565b6000806000606084860312156133fd576133fc612cd5565b5b600061340b86828701612f2b565b935050602061341c86828701612d00565b925050604061342d86828701612d00565b9150509250925092565b61344081612dc7565b811461344b57600080fd5b50565b60008135905061345d81613437565b92915050565b6000806040838503121561347a57613479612cd5565b5b600061348885828601612f2b565b92505060206134998582860161344e565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6134e082612e4c565b810181811067ffffffffffffffff821117156134ff576134fe6134a8565b5b80604052505050565b6000613512612ccb565b905061351e82826134d7565b919050565b600067ffffffffffffffff82111561353e5761353d6134a8565b5b61354782612e4c565b9050602081019050919050565b82818337600083830152505050565b600061357661357184613523565b613508565b905082815260208101848484011115613592576135916134a3565b5b61359d848285613554565b509392505050565b600082601f8301126135ba576135b961302a565b5b81356135ca848260208601613563565b91505092915050565b600080600080608085870312156135ed576135ec612cd5565b5b60006135fb87828801612f2b565b945050602061360c87828801612f2b565b935050604061361d87828801612d00565b925050606085013567ffffffffffffffff81111561363e5761363d612cda565b5b61364a878288016135a5565b91505092959194509250565b60808201600082015161366c60008501826131ab565b50602082015161367f60208501826131ce565b50604082015161369260408501826131dd565b5060608201516136a560608501826131fb565b50505050565b60006080820190506136c06000830184613656565b92915050565b600080604083850312156136dd576136dc612cd5565b5b60006136eb85828601612f2b565b92505060206136fc85828601612f2b565b9150509250929050565b7f4d494e54494e4720504155534544000000000000000000000000000000000000600082015250565b600061373c600e83612e08565b915061374782613706565b602082019050919050565b6000602082019050818103600083015261376b8161372f565b9050919050565b7f4d4158205045522057414c4c4554204953203500000000000000000000000000600082015250565b60006137a8601383612e08565b91506137b382613772565b602082019050919050565b600060208201905081810360008301526137d78161379b565b9050919050565b7f4d415820535550504c5920524541434845440000000000000000000000000000600082015250565b6000613814601283612e08565b915061381f826137de565b602082019050919050565b6000602082019050818103600083015261384381613807565b9050919050565b7f494e434f52524543542045544820414d4f554e54000000000000000000000000600082015250565b6000613880601483612e08565b915061388b8261384a565b602082019050919050565b600060208201905081810360008301526138af81613873565b9050919050565b7f554e415554484f52495a45440000000000000000000000000000000000000000600082015250565b60006138ec600c83612e08565b91506138f7826138b6565b602082019050919050565b6000602082019050818103600083015261391b816138df565b9050919050565b7f52455345525645532054414b454e000000000000000000000000000000000000600082015250565b6000613958600e83612e08565b915061396382613922565b602082019050919050565b600060208201905081810360008301526139878161394b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806139d557607f821691505b6020821081036139e8576139e761398e565b5b50919050565b6000604082019050613a036000830185612eea565b613a106020830184612eea565b9392505050565b600081519050613a2681613437565b92915050565b600060208284031215613a4257613a41612cd5565b5b6000613a5084828501613a17565b91505092915050565b7f554e5355434345535346554c0000000000000000000000000000000000000000600082015250565b6000613a8f600c83612e08565b9150613a9a82613a59565b602082019050919050565b60006020820190508181036000830152613abe81613a82565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081905092915050565b6000613b0a82612dfd565b613b148185613af4565b9350613b24818560208601612e19565b80840191505092915050565b6000613b3c8285613aff565b9150613b488284613aff565b91508190509392505050565b600081519050919050565b600082825260208201905092915050565b6000613b7b82613b54565b613b858185613b5f565b9350613b95818560208601612e19565b613b9e81612e4c565b840191505092915050565b6000608082019050613bbe6000830187612eea565b613bcb6020830186612eea565b613bd86040830185612fad565b8181036060830152613bea8184613b70565b905095945050505050565b600081519050613c0481612d6e565b92915050565b600060208284031215613c2057613c1f612cd5565b5b6000613c2e84828501613bf5565b9150509291505056fea2646970667358221220799a4bd362a6517405a48438040b7a459e0eeae597a10f6f01dd08f0adbac7ee64736f6c634300080d0033

Deployed Bytecode Sourcemap

110280:4413:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;111004:1387;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;24917:689;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113223:161;;;;;;;;;;;;;:::i;:::-;;25869:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32758:268;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113760:208;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69973:148;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;21442:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;112428:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113976:216;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113392:125;;;;;;;;;;;;;:::i;:::-;;114200:224;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113020:113;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63601:560;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;110729:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;27359:202;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22626:283;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113141:74;;;;;;;;;;;;;:::i;:::-;;67575:1016;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69337:20;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;110390:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26045:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;112546:121;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64549:2579;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;113525:227;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;114432:258;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;112675:123;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62964:478;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26255:415;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33789:214;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;111004:1387;111103:6;;;;;;;;;;;111102:7;111094:34;;;;;;;;;;;;:::i;:::-;;;;;;;;;110584:1;111201:9;111169:17;:29;111187:10;111169:29;;;;;;;;;;;;;;;;:41;:88;111143:169;;;;;;;;;;;;:::i;:::-;;;;;;;;;111329:20;111352:13;:11;:13::i;:::-;111329:36;;110530:4;111435:8;;111423:9;111408:12;:24;:35;:57;111382:137;;;;;;;;;;;;:::i;:::-;;;;;;;;;111536:19;111558:9;111536:31;;111582:23;111624:21;111648:16;:28;111665:10;111648:28;;;;;;;;;;;;;;;;111624:52;;111713:1;111697:13;:17;111693:301;;;111751:1;111739:9;:13;111735:153;;;111803:1;111791:9;:13;111777:27;;111735:153;;;111867:1;111853:15;;111735:153;111924:1;111906:19;;111977:1;111946:16;:28;111963:10;111946:28;;;;;;;;;;;;;;;:32;;;;111693:301;112041:9;112008:17;:29;112026:10;112008:29;;;;;;;;;;;;;;;;:42;;;;;;;;;;;112254:16;;112211:15;:59;110474:10;112128:11;:55;:142;112093:9;:178;;112067:260;;;;;;;;;;;;:::i;:::-;;;;;;;;;112344:28;112350:10;112362:9;112344:5;:28::i;:::-;111069:1315;;;;111004:1387;:::o;24917:689::-;25047:4;25391:10;25376:25;;:11;:25;;;;:102;;;;25468:10;25453:25;;:11;:25;;;;25376:102;:179;;;;25545:10;25530:25;;:11;:25;;;;25376:179;25356:199;;24917:689;;;:::o;113223:161::-;69428:5;;;;;;;;;;;69414:19;;:10;:19;;;69406:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;113299:1:::1;113288:8;;:12;113280:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;113332:21;113338:10;113350:2;113332:5;:21::i;:::-;113375:1;113364:8;:12;;;;113223:161::o:0;25869:100::-;25923:13;25956:5;25949:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25869:100;:::o;32758:268::-;32879:7;32909:16;32917:7;32909;:16::i;:::-;32904:64;;32934:34;;;;;;;;;;;;;;32904:64;32988:15;:24;33004:7;32988:24;;;;;;;;;;;:30;;;;;;;;;;;;32981:37;;32758:268;;;:::o;113760:208::-;113902:8;5278:1;3109:42;5230:45;;;:49;5226:318;;;3109:42;5319;;;5392:4;5420:8;5319:128;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5296:237;;5508:8;5489:28;;;;;;;;;;;:::i;:::-;;;;;;;;5296:237;5226:318;113928:32:::1;113942:8;113952:7;113928:13;:32::i;:::-;113760:208:::0;;;:::o;69973:148::-;69428:5;;;;;;;;;;;69414:19;;:10;:19;;;69406:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;70053:8:::1;70045:5;;:16;;;;;;;;;;;;;;;;;;70104:8;70079:34;;70092:10;70079:34;;;;;;;;;;;;69973:148:::0;:::o;21442:323::-;21503:7;21731:15;:13;:15::i;:::-;21716:12;;21700:13;;:28;:46;21693:53;;21442:323;:::o;112428:110::-;69428:5;;;;;;;;;;;69414:19;;:10;:19;;;69406:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;112521:9:::1;112502:16;:28;;;;112428:110:::0;:::o;113976:216::-;114130:4;4439:1;3109:42;4391:45;;;:49;4387:632;;;4680:10;4672:18;;:4;:18;;;4668:85;;114147:37:::1;114166:4;114172:2;114176:7;114147:18;:37::i;:::-;4731:7:::0;;4668:85;3109:42;4790;;;4863:4;4891:10;4790:130;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4767:241;;4981:10;4962:30;;;;;;;;;;;:::i;:::-;;;;;;;;4767:241;4387:632;114147:37:::1;114166:4;114172:2;114176:7;114147:18;:37::i;:::-;113976:216:::0;;;;;:::o;113392:125::-;69428:5;;;;;;;;;;;69414:19;;:10;:19;;;69406:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;113458:5:::1;;;;;;;;;;;113450:19;;:42;113470:21;113450:42;;;;;;;;;;;;;;;;;;;;;;;113442:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;113392:125::o:0;114200:224::-;114358:4;4439:1;3109:42;4391:45;;;:49;4387:632;;;4680:10;4672:18;;:4;:18;;;4668:85;;114375:41:::1;114398:4;114404:2;114408:7;114375:22;:41::i;:::-;4731:7:::0;;4668:85;3109:42;4790;;;4863:4;4891:10;4790:130;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4767:241;;4981:10;4962:30;;;;;;;;;;;:::i;:::-;;;;;;;;4767:241;4387:632;114375:41:::1;114398:4;114404:2;114408:7;114375:22;:41::i;:::-;114200:224:::0;;;;;:::o;113020:113::-;69428:5;;;;;;;;;;;69414:19;;:10;:19;;;69406:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;113114:11:::1;;113099:12;:26;;;;;;;:::i;:::-;;113020:113:::0;;:::o;63601:560::-;63745:23;63811:22;63836:8;;:15;;63811:40;;63866:34;63942:14;63903:68;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;63866:105;;63991:9;63986:125;64007:14;64002:1;:19;63986:125;;64063:32;64083:8;;64092:1;64083:11;;;;;;;:::i;:::-;;;;;;;;64063:19;:32::i;:::-;64047:10;64058:1;64047:13;;;;;;;;:::i;:::-;;;;;;;:48;;;;64023:3;;;;;63986:125;;;;64132:10;64125:17;;;;63601:560;;;;:::o;110729:25::-;;;;;;;;;;;;;:::o;27359:202::-;27476:7;27524:27;27543:7;27524:18;:27::i;:::-;27501:52;;27359:202;;;:::o;22626:283::-;22743:7;22789:1;22772:19;;:5;:19;;;22768:60;;22800:28;;;;;;;;;;;;;;22768:60;16785:13;22846:18;:25;22865:5;22846:25;;;;;;;;;;;;;;;;:55;22839:62;;22626:283;;;:::o;113141:74::-;69428:5;;;;;;;;;;;69414:19;;:10;:19;;;69406:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;113201:6:::1;;;;;;;;;;;113200:7;113191:6;;:16;;;;;;;;;;;;;;;;;;113141:74::o:0;67575:1016::-;67698:16;67757:19;67791:25;67831:22;67856:16;67866:5;67856:9;:16::i;:::-;67831:41;;67887:25;67929:14;67915:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67887:57;;67959:31;;:::i;:::-;68028:9;68040:15;:13;:15::i;:::-;68028:27;;68005:538;68089:14;68074:11;:29;68005:538;;68172:15;68185:1;68172:12;:15::i;:::-;68160:27;;68210:9;:16;;;68251:8;68206:73;68327:1;68301:28;;:9;:14;;;:28;;;68297:111;;68374:9;:14;;;68354:34;;68297:111;68451:5;68430:26;;:17;:26;;;68426:102;;68507:1;68481:8;68490:13;;;;;;68481:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;68426:102;68005:538;68122:3;;;;;68005:538;;;;68564:8;68557:15;;;;;;;67575:1016;;;:::o;69337:20::-;;;;;;;;;;;;;:::o;110390:41::-;;;;:::o;26045:104::-;26101:13;26134:7;26127:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26045:104;:::o;112546:121::-;112609:7;112636:16;:23;112653:5;112636:23;;;;;;;;;;;;;;;;112629:30;;112546:121;;;:::o;64549:2579::-;64692:16;64759:4;64750:5;:13;64746:45;;64772:19;;;;;;;;;;;;;;64746:45;64806:19;64840:17;64860:14;:12;:14::i;:::-;64840:34;;64960:15;:13;:15::i;:::-;64952:5;:23;64948:87;;;65004:15;:13;:15::i;:::-;64996:23;;64948:87;65111:9;65104:4;:16;65100:73;;;65148:9;65141:16;;65100:73;65187:25;65215:16;65225:5;65215:9;:16::i;:::-;65187:44;;65409:4;65401:5;:12;65397:278;;;65434:19;65463:5;65456:4;:12;65434:34;;65505:17;65491:11;:31;65487:111;;;65567:11;65547:31;;65487:111;65415:198;65397:278;;;65658:1;65638:21;;65397:278;65689:25;65731:17;65717:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65689:60;;65789:1;65768:17;:22;65764:78;;65818:8;65811:15;;;;;;;;65764:78;65986:31;66020:26;66040:5;66020:19;:26::i;:::-;65986:60;;66061:25;66306:9;:16;;;66301:92;;66363:9;:14;;;66343:34;;66301:92;66430:9;66442:5;66430:17;;66407:544;66471:4;66466:1;:9;;:45;;;;;66494:17;66479:11;:32;;66466:45;66407:544;;;66580:15;66593:1;66580:12;:15::i;:::-;66568:27;;66618:9;:16;;;66659:8;66614:73;66735:1;66709:28;;:9;:14;;;:28;;;66705:111;;66782:9;:14;;;66762:34;;66705:111;66859:5;66838:26;;:17;:26;;;66834:102;;66915:1;66889:8;66898:13;;;;;;66889:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;66834:102;66407:544;66530:3;;;;;66407:544;;;;67053:11;67043:8;67036:29;67101:8;67094:15;;;;;;;;64549:2579;;;;;;:::o;113525:227::-;113675:8;5278:1;3109:42;5230:45;;;:49;5226:318;;;3109:42;5319;;;5392:4;5420:8;5319:128;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5296:237;;5508:8;5489:28;;;;;;;;;;;:::i;:::-;;;;;;;;5296:237;5226:318;113701:43:::1;113725:8;113735;113701:23;:43::i;:::-;113525:227:::0;;;:::o;114432:258::-;114618:4;4439:1;3109:42;4391:45;;;:49;4387:632;;;4680:10;4672:18;;:4;:18;;;4668:85;;114635:47:::1;114658:4;114664:2;114668:7;114677:4;114635:22;:47::i;:::-;4731:7:::0;;4668:85;3109:42;4790;;;4863:4;4891:10;4790:130;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4767:241;;4981:10;4962:30;;;;;;;;;;;:::i;:::-;;;;;;;;4767:241;4387:632;114635:47:::1;114658:4;114664:2;114668:7;114677:4;114635:22;:47::i;:::-;114432:258:::0;;;;;;:::o;112675:123::-;112739:7;112766:17;:24;112784:5;112766:24;;;;;;;;;;;;;;;;112759:31;;112675:123;;;:::o;62964:478::-;63093:21;;:::i;:::-;63132:31;;:::i;:::-;63188:15;:13;:15::i;:::-;63178:7;:25;:54;;;;63218:14;:12;:14::i;:::-;63207:7;:25;;63178:54;63174:103;;;63256:9;63249:16;;;;;63174:103;63299:21;63312:7;63299:12;:21::i;:::-;63287:33;;63335:9;:16;;;63331:65;;;63375:9;63368:16;;;;;63331:65;63413:21;63426:7;63413:12;:21::i;:::-;63406:28;;;62964:478;;;;:::o;26255:415::-;26373:13;26409:16;26417:7;26409;:16::i;:::-;26404:59;;26434:29;;;;;;;;;;;;;;26404:59;26476:21;26500:10;:8;:10::i;:::-;26476:34;;26566:1;26547:7;26541:21;:26;:121;;;;;;;;;;;;;;;;;26611:7;26620:18;26630:7;26620:9;:18::i;:::-;26594:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;26541:121;26521:141;;;26255:415;;;:::o;33789:214::-;33931:4;33960:18;:25;33979:5;33960:25;;;;;;;;;;;;;;;:35;33986:8;33960:35;;;;;;;;;;;;;;;;;;;;;;;;;33953:42;;33789:214;;;;:::o;44179:2775::-;44252:20;44275:13;;44252:36;;44315:1;44303:8;:13;44299:44;;44325:18;;;;;;;;;;;;;;44299:44;44356:61;44386:1;44390:2;44394:12;44408:8;44356:21;:61::i;:::-;44934:1;16923:2;44904:1;:26;;44903:32;44874:8;:62;44831:18;:22;44850:2;44831:22;;;;;;;;;;;;;;;;:105;;;;;;;;;;;45213:160;45250:2;45325:33;45348:1;45352:2;45356:1;45325:14;:33::i;:::-;45271:30;45292:8;45271:20;:30::i;:::-;:87;45213:18;:160::i;:::-;45179:17;:31;45197:12;45179:31;;;;;;;;;;;:194;;;;45390:16;45421:11;45450:8;45435:12;:23;45421:37;;45971:16;45967:2;45963:25;45951:37;;46343:12;46303:8;46262:1;46200:25;46141:1;46080;46053:335;46468:1;46454:12;46450:20;46408:346;46509:3;46500:7;46497:16;46408:346;;46727:7;46717:8;46714:1;46687:25;46684:1;46681;46676:59;46562:1;46553:7;46549:15;46538:26;;46408:346;;;46412:77;46799:1;46787:8;:13;46783:45;;46809:19;;;;;;;;;;;;;;46783:45;46861:3;46845:13;:19;;;;44605:2271;;46886:60;46915:1;46919:2;46923:12;46937:8;46886:20;:60::i;:::-;44241:2713;44179:2775;;:::o;34261:282::-;34326:4;34382:7;34363:15;:13;:15::i;:::-;:26;;:66;;;;;34416:13;;34406:7;:23;34363:66;:153;;;;;34515:1;17561:8;34467:17;:26;34485:7;34467:26;;;;;;;;;;;;:44;:49;34363:153;34343:173;;34261:282;;;:::o;32199:400::-;32280:13;32296:16;32304:7;32296;:16::i;:::-;32280:32;;32352:5;32329:28;;:19;:17;:19::i;:::-;:28;;;32325:175;;32377:44;32394:5;32401:19;:17;:19::i;:::-;32377:16;:44::i;:::-;32372:128;;32449:35;;;;;;;;;;;;;;32372:128;32325:175;32545:2;32512:15;:24;32528:7;32512:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;32583:7;32579:2;32563:28;;32572:5;32563:28;;;;;;;;;;;;32269:330;32199:400;;:::o;112806:93::-;112863:7;112890:1;112883:8;;112806:93;:::o;36529:2995::-;36663:27;36693;36712:7;36693:18;:27::i;:::-;36663:57;;36778:4;36737:45;;36753:19;36737:45;;;36733:99;;36804:28;;;;;;;;;;;;;;36733:99;36860:27;36902:23;36939:35;36966:7;36939:26;:35::i;:::-;36845:129;;;;37088:134;37131:15;37165:4;37188:19;:17;:19::i;:::-;37088:24;:134::i;:::-;37069:287;;37252:43;37269:4;37275:19;:17;:19::i;:::-;37252:16;:43::i;:::-;37247:109;;37321:35;;;;;;;;;;;;;;37247:109;37069:287;37387:1;37373:16;;:2;:16;;;37369:52;;37398:23;;;;;;;;;;;;;;37369:52;37434:43;37456:4;37462:2;37466:7;37475:1;37434:21;:43::i;:::-;37570:15;37567:160;;;37710:1;37689:19;37682:30;37567:160;38107:18;:24;38126:4;38107:24;;;;;;;;;;;;;;;;38105:26;;;;;;;;;;;;38176:18;:22;38195:2;38176:22;;;;;;;;;;;;;;;;38174:24;;;;;;;;;;;38498:167;38535:2;38605:45;38620:4;38626:2;38630:19;38605:14;:45::i;:::-;17841:8;38556:94;38498:18;:167::i;:::-;38469:17;:26;38487:7;38469:26;;;;;;;;;;;:196;;;;38836:1;17841:8;38785:19;:47;:52;38781:627;;38858:19;38890:1;38880:7;:11;38858:33;;39047:1;39013:17;:30;39031:11;39013:30;;;;;;;;;;;;:35;39009:384;;39151:13;;39136:11;:28;39132:242;;39331:19;39298:17;:30;39316:11;39298:30;;;;;;;;;;;:52;;;;39132:242;39009:384;38839:569;38781:627;39455:7;39451:2;39436:27;;39445:4;39436:27;;;;;;;;;;;;39474:42;39495:4;39501:2;39505:7;39514:1;39474:20;:42::i;:::-;36652:2872;;;36529:2995;;;:::o;39620:185::-;39758:39;39775:4;39781:2;39785:7;39758:39;;;;;;;;;;;;:16;:39::i;:::-;39620:185;;;:::o;28646:1307::-;28740:7;28765:12;28780:7;28765:22;;28848:4;28829:15;:13;:15::i;:::-;:23;28825:1061;;28882:13;;28875:4;:20;28871:1015;;;28920:14;28937:17;:23;28955:4;28937:23;;;;;;;;;;;;28920:40;;29054:1;17561:8;29026:6;:24;:29;29022:845;;29691:113;29708:1;29698:6;:11;29691:113;;29751:17;:25;29769:6;;;;;;;29751:25;;;;;;;;;;;;29742:34;;29691:113;;;29837:6;29830:13;;;;;;29022:845;28897:989;28871:1015;28825:1061;29914:31;;;;;;;;;;;;;;28646:1307;;;;:::o;28053:202::-;28157:21;;:::i;:::-;28203:44;28222:17;:24;28240:5;28222:24;;;;;;;;;;;;28203:18;:44::i;:::-;28196:51;;28053:202;;;:::o;21129:103::-;21184:7;21211:13;;21204:20;;21129:103;:::o;33366:266::-;33545:8;33493:18;:39;33512:19;:17;:19::i;:::-;33493:39;;;;;;;;;;;;;;;:49;33533:8;33493:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;33605:8;33569:55;;33584:19;:17;:19::i;:::-;33569:55;;;33615:8;33569:55;;;;;;:::i;:::-;;;;;;;;33366:266;;:::o;40403:399::-;40570:31;40583:4;40589:2;40593:7;40570:12;:31::i;:::-;40634:1;40616:2;:14;;;:19;40612:183;;40655:56;40686:4;40692:2;40696:7;40705:5;40655:30;:56::i;:::-;40650:145;;40739:40;;;;;;;;;;;;;;40650:145;40612:183;40403:399;;;;:::o;27750:207::-;27856:21;;:::i;:::-;27902:47;27921:27;27940:7;27921:18;:27::i;:::-;27902:18;:47::i;:::-;27895:54;;27750:207;;;:::o;112907:105::-;112959:13;112992:12;112985:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;112907:105;:::o;57415:1786::-;57516:17;57955:4;57948;57942:11;57938:22;58047:1;58041:4;58034:15;58122:4;58119:1;58115:12;58108:19;;58204:1;58199:3;58192:14;58308:3;58547:5;58529:428;58555:1;58529:428;;;58595:1;58590:3;58586:11;58579:18;;58766:2;58760:4;58756:13;58752:2;58748:22;58743:3;58735:36;58860:2;58854:4;58850:13;58842:21;;58927:4;58529:428;58917:25;58529:428;58533:21;58996:3;58991;58987:13;59111:4;59106:3;59102:14;59095:21;;59176:6;59171:3;59164:19;57560:1634;;;57415:1786;;;:::o;41464:159::-;;;;;:::o;56517:311::-;56652:7;56672:16;17965:3;56698:19;:41;;56672:68;;17965:3;56766:31;56777:4;56783:2;56787:9;56766:10;:31::i;:::-;56758:40;;:62;;56751:69;;;56517:311;;;;;:::o;31166:356::-;31263:14;31501:1;31491:8;31488:15;31462:24;31458:46;31448:56;;31166:356;;;:::o;30533:531::-;30640:14;30813:16;30806:5;30802:28;30793:37;;31025:5;31011:11;30986:23;30982:41;30979:52;30955:5;30934:112;30924:122;;30533:531;;;;:::o;42288:158::-;;;;;:::o;57208:105::-;57268:7;57295:10;57288:17;;57208:105;:::o;35424:485::-;35526:27;35555:23;35596:38;35637:15;:24;35653:7;35637:24;;;;;;;;;;;35596:65;;35814:18;35791:41;;35871:19;35865:26;35846:45;;35776:126;35424:485;;;:::o;34652:659::-;34801:11;34966:16;34959:5;34955:28;34946:37;;35126:16;35115:9;35111:32;35098:45;;35276:15;35265:9;35262:30;35254:5;35243:9;35240:20;35237:56;35227:66;;34652:659;;;;;:::o;30052:398::-;30145:31;;:::i;:::-;30227:6;30194:9;:14;;:41;;;;;;;;;;;17444:3;30280:6;:33;;30246:9;:24;;:68;;;;;;;;;;;30372:1;17561:8;30344:6;:24;:29;;30325:9;:16;;:48;;;;;;;;;;;17965:3;30413:6;:28;;30384:9;:19;;:58;;;;;;;;;;;30052:398;;;:::o;42886:831::-;43049:4;43108:2;43083:45;;;43147:19;:17;:19::i;:::-;43185:4;43208:7;43234:5;43083:171;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;43066:644;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43485:1;43468:6;:13;:18;43464:235;;43514:40;;;;;;;;;;;;;;43464:235;43657:6;43651:13;43642:6;43638:2;43634:15;43627:38;43066:644;43354:54;;;43327:81;;;:6;:81;;;;43303:105;;;42886:831;;;;;;:::o;56218:147::-;56355:6;56218:147;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::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:307::-;2557:1;2567:113;2581:6;2578:1;2575:13;2567:113;;;2666:1;2661:3;2657:11;2651:18;2647:1;2642:3;2638:11;2631:39;2603:2;2600:1;2596:10;2591:15;;2567:113;;;2698:6;2695:1;2692:13;2689:101;;;2778:1;2769:6;2764:3;2760:16;2753:27;2689:101;2538:258;2489:307;;;:::o;2802:102::-;2843:6;2894:2;2890:7;2885:2;2878:5;2874:14;2870:28;2860:38;;2802:102;;;:::o;2910:364::-;2998:3;3026:39;3059:5;3026:39;:::i;:::-;3081:71;3145:6;3140:3;3081:71;:::i;:::-;3074:78;;3161:52;3206:6;3201:3;3194:4;3187:5;3183:16;3161:52;:::i;:::-;3238:29;3260:6;3238:29;:::i;:::-;3233:3;3229:39;3222:46;;3002:272;2910:364;;;;:::o;3280:313::-;3393:4;3431:2;3420:9;3416:18;3408:26;;3480:9;3474:4;3470:20;3466:1;3455:9;3451:17;3444:47;3508:78;3581:4;3572:6;3508:78;:::i;:::-;3500:86;;3280:313;;;;:::o;3599:126::-;3636:7;3676:42;3669:5;3665:54;3654:65;;3599:126;;;:::o;3731:96::-;3768:7;3797:24;3815:5;3797:24;:::i;:::-;3786:35;;3731:96;;;:::o;3833:118::-;3920:24;3938:5;3920:24;:::i;:::-;3915:3;3908:37;3833:118;;:::o;3957:222::-;4050:4;4088:2;4077:9;4073:18;4065:26;;4101:71;4169:1;4158:9;4154:17;4145:6;4101:71;:::i;:::-;3957:222;;;;:::o;4185:122::-;4258:24;4276:5;4258:24;:::i;:::-;4251:5;4248:35;4238:63;;4297:1;4294;4287:12;4238:63;4185:122;:::o;4313:139::-;4359:5;4397:6;4384:20;4375:29;;4413:33;4440:5;4413:33;:::i;:::-;4313:139;;;;:::o;4458:474::-;4526:6;4534;4583:2;4571:9;4562:7;4558:23;4554:32;4551:119;;;4589:79;;:::i;:::-;4551:119;4709:1;4734:53;4779:7;4770:6;4759:9;4755:22;4734:53;:::i;:::-;4724:63;;4680:117;4836:2;4862:53;4907:7;4898:6;4887:9;4883:22;4862:53;:::i;:::-;4852:63;;4807:118;4458:474;;;;;:::o;4938:329::-;4997:6;5046:2;5034:9;5025:7;5021:23;5017:32;5014:119;;;5052:79;;:::i;:::-;5014:119;5172:1;5197:53;5242:7;5233:6;5222:9;5218:22;5197:53;:::i;:::-;5187:63;;5143:117;4938:329;;;;:::o;5273:118::-;5360:24;5378:5;5360:24;:::i;:::-;5355:3;5348:37;5273:118;;:::o;5397:222::-;5490:4;5528:2;5517:9;5513:18;5505:26;;5541:71;5609:1;5598:9;5594:17;5585:6;5541:71;:::i;:::-;5397:222;;;;:::o;5625:619::-;5702:6;5710;5718;5767:2;5755:9;5746:7;5742:23;5738:32;5735:119;;;5773:79;;:::i;:::-;5735:119;5893:1;5918:53;5963:7;5954:6;5943:9;5939:22;5918:53;:::i;:::-;5908:63;;5864:117;6020:2;6046:53;6091:7;6082:6;6071:9;6067:22;6046:53;:::i;:::-;6036:63;;5991:118;6148:2;6174:53;6219:7;6210:6;6199:9;6195:22;6174:53;:::i;:::-;6164:63;;6119:118;5625:619;;;;;:::o;6250:117::-;6359:1;6356;6349:12;6373:117;6482:1;6479;6472:12;6496:117;6605:1;6602;6595:12;6633:553;6691:8;6701:6;6751:3;6744:4;6736:6;6732:17;6728:27;6718:122;;6759:79;;:::i;:::-;6718:122;6872:6;6859:20;6849:30;;6902:18;6894:6;6891:30;6888:117;;;6924:79;;:::i;:::-;6888:117;7038:4;7030:6;7026:17;7014:29;;7092:3;7084:4;7076:6;7072:17;7062:8;7058:32;7055:41;7052:128;;;7099:79;;:::i;:::-;7052:128;6633:553;;;;;:::o;7192:529::-;7263:6;7271;7320:2;7308:9;7299:7;7295:23;7291:32;7288:119;;;7326:79;;:::i;:::-;7288:119;7474:1;7463:9;7459:17;7446:31;7504:18;7496:6;7493:30;7490:117;;;7526:79;;:::i;:::-;7490:117;7639:65;7696:7;7687:6;7676:9;7672:22;7639:65;:::i;:::-;7621:83;;;;7417:297;7192:529;;;;;:::o;7744:568::-;7817:8;7827:6;7877:3;7870:4;7862:6;7858:17;7854:27;7844:122;;7885:79;;:::i;:::-;7844:122;7998:6;7985:20;7975:30;;8028:18;8020:6;8017:30;8014:117;;;8050:79;;:::i;:::-;8014:117;8164:4;8156:6;8152:17;8140:29;;8218:3;8210:4;8202:6;8198:17;8188:8;8184:32;8181:41;8178:128;;;8225:79;;:::i;:::-;8178:128;7744:568;;;;;:::o;8318:559::-;8404:6;8412;8461:2;8449:9;8440:7;8436:23;8432:32;8429:119;;;8467:79;;:::i;:::-;8429:119;8615:1;8604:9;8600:17;8587:31;8645:18;8637:6;8634:30;8631:117;;;8667:79;;:::i;:::-;8631:117;8780:80;8852:7;8843:6;8832:9;8828:22;8780:80;:::i;:::-;8762:98;;;;8558:312;8318:559;;;;;:::o;8883:145::-;8981:6;9015:5;9009:12;8999:22;;8883:145;;;:::o;9034:215::-;9164:11;9198:6;9193:3;9186:19;9238:4;9233:3;9229:14;9214:29;;9034:215;;;;:::o;9255:163::-;9353:4;9376:3;9368:11;;9406:4;9401:3;9397:14;9389:22;;9255:163;;;:::o;9424:108::-;9501:24;9519:5;9501:24;:::i;:::-;9496:3;9489:37;9424:108;;:::o;9538:101::-;9574:7;9614:18;9607:5;9603:30;9592:41;;9538:101;;;:::o;9645:105::-;9720:23;9737:5;9720:23;:::i;:::-;9715:3;9708:36;9645:105;;:::o;9756:99::-;9827:21;9842:5;9827:21;:::i;:::-;9822:3;9815:34;9756:99;;:::o;9861:91::-;9897:7;9937:8;9930:5;9926:20;9915:31;;9861:91;;;:::o;9958:105::-;10033:23;10050:5;10033:23;:::i;:::-;10028:3;10021:36;9958:105;;:::o;10141:864::-;10290:4;10285:3;10281:14;10377:4;10370:5;10366:16;10360:23;10396:63;10453:4;10448:3;10444:14;10430:12;10396:63;:::i;:::-;10305:164;10561:4;10554:5;10550:16;10544:23;10580:61;10635:4;10630:3;10626:14;10612:12;10580:61;:::i;:::-;10479:172;10735:4;10728:5;10724:16;10718:23;10754:57;10805:4;10800:3;10796:14;10782:12;10754:57;:::i;:::-;10661:160;10908:4;10901:5;10897:16;10891:23;10927:61;10982:4;10977:3;10973:14;10959:12;10927:61;:::i;:::-;10831:167;10259:746;10141:864;;:::o;11011:303::-;11142:10;11163:108;11267:3;11259:6;11163:108;:::i;:::-;11303:4;11298:3;11294:14;11280:28;;11011:303;;;;:::o;11320:144::-;11421:4;11453;11448:3;11444:14;11436:22;;11320:144;;;:::o;11546:980::-;11727:3;11756:85;11835:5;11756:85;:::i;:::-;11857:117;11967:6;11962:3;11857:117;:::i;:::-;11850:124;;11998:87;12079:5;11998:87;:::i;:::-;12108:7;12139:1;12124:377;12149:6;12146:1;12143:13;12124:377;;;12225:6;12219:13;12252:125;12373:3;12358:13;12252:125;:::i;:::-;12245:132;;12400:91;12484:6;12400:91;:::i;:::-;12390:101;;12184:317;12171:1;12168;12164:9;12159:14;;12124:377;;;12128:14;12517:3;12510:10;;11732:794;;;11546:980;;;;:::o;12532:497::-;12737:4;12775:2;12764:9;12760:18;12752:26;;12824:9;12818:4;12814:20;12810:1;12799:9;12795:17;12788:47;12852:170;13017:4;13008:6;12852:170;:::i;:::-;12844:178;;12532:497;;;;:::o;13035:114::-;13102:6;13136:5;13130:12;13120:22;;13035:114;;;:::o;13155:184::-;13254:11;13288:6;13283:3;13276:19;13328:4;13323:3;13319:14;13304:29;;13155:184;;;;:::o;13345:132::-;13412:4;13435:3;13427:11;;13465:4;13460:3;13456:14;13448:22;;13345:132;;;:::o;13483:108::-;13560:24;13578:5;13560:24;:::i;:::-;13555:3;13548:37;13483:108;;:::o;13597:179::-;13666:10;13687:46;13729:3;13721:6;13687:46;:::i;:::-;13765:4;13760:3;13756:14;13742:28;;13597:179;;;;:::o;13782:113::-;13852:4;13884;13879:3;13875:14;13867:22;;13782:113;;;:::o;13931:732::-;14050:3;14079:54;14127:5;14079:54;:::i;:::-;14149:86;14228:6;14223:3;14149:86;:::i;:::-;14142:93;;14259:56;14309:5;14259:56;:::i;:::-;14338:7;14369:1;14354:284;14379:6;14376:1;14373:13;14354:284;;;14455:6;14449:13;14482:63;14541:3;14526:13;14482:63;:::i;:::-;14475:70;;14568:60;14621:6;14568:60;:::i;:::-;14558:70;;14414:224;14401:1;14398;14394:9;14389:14;;14354:284;;;14358:14;14654:3;14647:10;;14055:608;;;13931:732;;;;:::o;14669:373::-;14812:4;14850:2;14839:9;14835:18;14827:26;;14899:9;14893:4;14889:20;14885:1;14874:9;14870:17;14863:47;14927:108;15030:4;15021:6;14927:108;:::i;:::-;14919:116;;14669:373;;;;:::o;15048:619::-;15125:6;15133;15141;15190:2;15178:9;15169:7;15165:23;15161:32;15158:119;;;15196:79;;:::i;:::-;15158:119;15316:1;15341:53;15386:7;15377:6;15366:9;15362:22;15341:53;:::i;:::-;15331:63;;15287:117;15443:2;15469:53;15514:7;15505:6;15494:9;15490:22;15469:53;:::i;:::-;15459:63;;15414:118;15571:2;15597:53;15642:7;15633:6;15622:9;15618:22;15597:53;:::i;:::-;15587:63;;15542:118;15048:619;;;;;:::o;15673:116::-;15743:21;15758:5;15743:21;:::i;:::-;15736:5;15733:32;15723:60;;15779:1;15776;15769:12;15723:60;15673:116;:::o;15795:133::-;15838:5;15876:6;15863:20;15854:29;;15892:30;15916:5;15892:30;:::i;:::-;15795:133;;;;:::o;15934:468::-;15999:6;16007;16056:2;16044:9;16035:7;16031:23;16027:32;16024:119;;;16062:79;;:::i;:::-;16024:119;16182:1;16207:53;16252:7;16243:6;16232:9;16228:22;16207:53;:::i;:::-;16197:63;;16153:117;16309:2;16335:50;16377:7;16368:6;16357:9;16353:22;16335:50;:::i;:::-;16325:60;;16280:115;15934:468;;;;;:::o;16408:117::-;16517:1;16514;16507:12;16531:180;16579:77;16576:1;16569:88;16676:4;16673:1;16666:15;16700:4;16697:1;16690:15;16717:281;16800:27;16822:4;16800:27;:::i;:::-;16792:6;16788:40;16930:6;16918:10;16915:22;16894:18;16882:10;16879:34;16876:62;16873:88;;;16941:18;;:::i;:::-;16873:88;16981:10;16977:2;16970:22;16760:238;16717:281;;:::o;17004:129::-;17038:6;17065:20;;:::i;:::-;17055:30;;17094:33;17122:4;17114:6;17094:33;:::i;:::-;17004:129;;;:::o;17139:307::-;17200:4;17290:18;17282:6;17279:30;17276:56;;;17312:18;;:::i;:::-;17276:56;17350:29;17372:6;17350:29;:::i;:::-;17342:37;;17434:4;17428;17424:15;17416:23;;17139:307;;;:::o;17452:154::-;17536:6;17531:3;17526;17513:30;17598:1;17589:6;17584:3;17580:16;17573:27;17452:154;;;:::o;17612:410::-;17689:5;17714:65;17730:48;17771:6;17730:48;:::i;:::-;17714:65;:::i;:::-;17705:74;;17802:6;17795:5;17788:21;17840:4;17833:5;17829:16;17878:3;17869:6;17864:3;17860:16;17857:25;17854:112;;;17885:79;;:::i;:::-;17854:112;17975:41;18009:6;18004:3;17999;17975:41;:::i;:::-;17695:327;17612:410;;;;;:::o;18041:338::-;18096:5;18145:3;18138:4;18130:6;18126:17;18122:27;18112:122;;18153:79;;:::i;:::-;18112:122;18270:6;18257:20;18295:78;18369:3;18361:6;18354:4;18346:6;18342:17;18295:78;:::i;:::-;18286:87;;18102:277;18041:338;;;;:::o;18385:943::-;18480:6;18488;18496;18504;18553:3;18541:9;18532:7;18528:23;18524:33;18521:120;;;18560:79;;:::i;:::-;18521:120;18680:1;18705:53;18750:7;18741:6;18730:9;18726:22;18705:53;:::i;:::-;18695:63;;18651:117;18807:2;18833:53;18878:7;18869:6;18858:9;18854:22;18833:53;:::i;:::-;18823:63;;18778:118;18935:2;18961:53;19006:7;18997:6;18986:9;18982:22;18961:53;:::i;:::-;18951:63;;18906:118;19091:2;19080:9;19076:18;19063:32;19122:18;19114:6;19111:30;19108:117;;;19144:79;;:::i;:::-;19108:117;19249:62;19303:7;19294:6;19283:9;19279:22;19249:62;:::i;:::-;19239:72;;19034:287;18385:943;;;;;;;:::o;19406:874::-;19565:4;19560:3;19556:14;19652:4;19645:5;19641:16;19635:23;19671:63;19728:4;19723:3;19719:14;19705:12;19671:63;:::i;:::-;19580:164;19836:4;19829:5;19825:16;19819:23;19855:61;19910:4;19905:3;19901:14;19887:12;19855:61;:::i;:::-;19754:172;20010:4;20003:5;19999:16;19993:23;20029:57;20080:4;20075:3;20071:14;20057:12;20029:57;:::i;:::-;19936:160;20183:4;20176:5;20172:16;20166:23;20202:61;20257:4;20252:3;20248:14;20234:12;20202:61;:::i;:::-;20106:167;19534:746;19406:874;;:::o;20286:347::-;20441:4;20479:3;20468:9;20464:19;20456:27;;20493:133;20623:1;20612:9;20608:17;20599:6;20493:133;:::i;:::-;20286:347;;;;:::o;20639:474::-;20707:6;20715;20764:2;20752:9;20743:7;20739:23;20735:32;20732:119;;;20770:79;;:::i;:::-;20732:119;20890:1;20915:53;20960:7;20951:6;20940:9;20936:22;20915:53;:::i;:::-;20905:63;;20861:117;21017:2;21043:53;21088:7;21079:6;21068:9;21064:22;21043:53;:::i;:::-;21033:63;;20988:118;20639:474;;;;;:::o;21119:164::-;21259:16;21255:1;21247:6;21243:14;21236:40;21119:164;:::o;21289:366::-;21431:3;21452:67;21516:2;21511:3;21452:67;:::i;:::-;21445:74;;21528:93;21617:3;21528:93;:::i;:::-;21646:2;21641:3;21637:12;21630:19;;21289:366;;;:::o;21661:419::-;21827:4;21865:2;21854:9;21850:18;21842:26;;21914:9;21908:4;21904:20;21900:1;21889:9;21885:17;21878:47;21942:131;22068:4;21942:131;:::i;:::-;21934:139;;21661:419;;;:::o;22086:169::-;22226:21;22222:1;22214:6;22210:14;22203:45;22086:169;:::o;22261:366::-;22403:3;22424:67;22488:2;22483:3;22424:67;:::i;:::-;22417:74;;22500:93;22589:3;22500:93;:::i;:::-;22618:2;22613:3;22609:12;22602:19;;22261:366;;;:::o;22633:419::-;22799:4;22837:2;22826:9;22822:18;22814:26;;22886:9;22880:4;22876:20;22872:1;22861:9;22857:17;22850:47;22914:131;23040:4;22914:131;:::i;:::-;22906:139;;22633:419;;;:::o;23058:168::-;23198:20;23194:1;23186:6;23182:14;23175:44;23058:168;:::o;23232:366::-;23374:3;23395:67;23459:2;23454:3;23395:67;:::i;:::-;23388:74;;23471:93;23560:3;23471:93;:::i;:::-;23589:2;23584:3;23580:12;23573:19;;23232:366;;;:::o;23604:419::-;23770:4;23808:2;23797:9;23793:18;23785:26;;23857:9;23851:4;23847:20;23843:1;23832:9;23828:17;23821:47;23885:131;24011:4;23885:131;:::i;:::-;23877:139;;23604:419;;;:::o;24029:170::-;24169:22;24165:1;24157:6;24153:14;24146:46;24029:170;:::o;24205:366::-;24347:3;24368:67;24432:2;24427:3;24368:67;:::i;:::-;24361:74;;24444:93;24533:3;24444:93;:::i;:::-;24562:2;24557:3;24553:12;24546:19;;24205:366;;;:::o;24577:419::-;24743:4;24781:2;24770:9;24766:18;24758:26;;24830:9;24824:4;24820:20;24816:1;24805:9;24801:17;24794:47;24858:131;24984:4;24858:131;:::i;:::-;24850:139;;24577:419;;;:::o;25002:162::-;25142:14;25138:1;25130:6;25126:14;25119:38;25002:162;:::o;25170:366::-;25312:3;25333:67;25397:2;25392:3;25333:67;:::i;:::-;25326:74;;25409:93;25498:3;25409:93;:::i;:::-;25527:2;25522:3;25518:12;25511:19;;25170:366;;;:::o;25542:419::-;25708:4;25746:2;25735:9;25731:18;25723:26;;25795:9;25789:4;25785:20;25781:1;25770:9;25766:17;25759:47;25823:131;25949:4;25823:131;:::i;:::-;25815:139;;25542:419;;;:::o;25967:164::-;26107:16;26103:1;26095:6;26091:14;26084:40;25967:164;:::o;26137:366::-;26279:3;26300:67;26364:2;26359:3;26300:67;:::i;:::-;26293:74;;26376:93;26465:3;26376:93;:::i;:::-;26494:2;26489:3;26485:12;26478:19;;26137:366;;;:::o;26509:419::-;26675:4;26713:2;26702:9;26698:18;26690:26;;26762:9;26756:4;26752:20;26748:1;26737:9;26733:17;26726:47;26790:131;26916:4;26790:131;:::i;:::-;26782:139;;26509:419;;;:::o;26934:180::-;26982:77;26979:1;26972:88;27079:4;27076:1;27069:15;27103:4;27100:1;27093:15;27120:320;27164:6;27201:1;27195:4;27191:12;27181:22;;27248:1;27242:4;27238:12;27269:18;27259:81;;27325:4;27317:6;27313:17;27303:27;;27259:81;27387:2;27379:6;27376:14;27356:18;27353:38;27350:84;;27406:18;;:::i;:::-;27350:84;27171:269;27120:320;;;:::o;27446:332::-;27567:4;27605:2;27594:9;27590:18;27582:26;;27618:71;27686:1;27675:9;27671:17;27662:6;27618:71;:::i;:::-;27699:72;27767:2;27756:9;27752:18;27743:6;27699:72;:::i;:::-;27446:332;;;;;:::o;27784:137::-;27838:5;27869:6;27863:13;27854:22;;27885:30;27909:5;27885:30;:::i;:::-;27784:137;;;;:::o;27927:345::-;27994:6;28043:2;28031:9;28022:7;28018:23;28014:32;28011:119;;;28049:79;;:::i;:::-;28011:119;28169:1;28194:61;28247:7;28238:6;28227:9;28223:22;28194:61;:::i;:::-;28184:71;;28140:125;27927:345;;;;:::o;28278:162::-;28418:14;28414:1;28406:6;28402:14;28395:38;28278:162;:::o;28446:366::-;28588:3;28609:67;28673:2;28668:3;28609:67;:::i;:::-;28602:74;;28685:93;28774:3;28685:93;:::i;:::-;28803:2;28798:3;28794:12;28787:19;;28446:366;;;:::o;28818:419::-;28984:4;29022:2;29011:9;29007:18;28999:26;;29071:9;29065:4;29061:20;29057:1;29046:9;29042:17;29035:47;29099:131;29225:4;29099:131;:::i;:::-;29091:139;;28818:419;;;:::o;29243:180::-;29291:77;29288:1;29281:88;29388:4;29385:1;29378:15;29412:4;29409:1;29402:15;29429:148;29531:11;29568:3;29553:18;;29429:148;;;;:::o;29583:377::-;29689:3;29717:39;29750:5;29717:39;:::i;:::-;29772:89;29854:6;29849:3;29772:89;:::i;:::-;29765:96;;29870:52;29915:6;29910:3;29903:4;29896:5;29892:16;29870:52;:::i;:::-;29947:6;29942:3;29938:16;29931:23;;29693:267;29583:377;;;;:::o;29966:435::-;30146:3;30168:95;30259:3;30250:6;30168:95;:::i;:::-;30161:102;;30280:95;30371:3;30362:6;30280:95;:::i;:::-;30273:102;;30392:3;30385:10;;29966:435;;;;;:::o;30407:98::-;30458:6;30492:5;30486:12;30476:22;;30407:98;;;:::o;30511:168::-;30594:11;30628:6;30623:3;30616:19;30668:4;30663:3;30659:14;30644:29;;30511:168;;;;:::o;30685:360::-;30771:3;30799:38;30831:5;30799:38;:::i;:::-;30853:70;30916:6;30911:3;30853:70;:::i;:::-;30846:77;;30932:52;30977:6;30972:3;30965:4;30958:5;30954:16;30932:52;:::i;:::-;31009:29;31031:6;31009:29;:::i;:::-;31004:3;31000:39;30993:46;;30775:270;30685:360;;;;:::o;31051:640::-;31246:4;31284:3;31273:9;31269:19;31261:27;;31298:71;31366:1;31355:9;31351:17;31342:6;31298:71;:::i;:::-;31379:72;31447:2;31436:9;31432:18;31423:6;31379:72;:::i;:::-;31461;31529:2;31518:9;31514:18;31505:6;31461:72;:::i;:::-;31580:9;31574:4;31570:20;31565:2;31554:9;31550:18;31543:48;31608:76;31679:4;31670:6;31608:76;:::i;:::-;31600:84;;31051:640;;;;;;;:::o;31697:141::-;31753:5;31784:6;31778:13;31769:22;;31800:32;31826:5;31800:32;:::i;:::-;31697:141;;;;:::o;31844:349::-;31913:6;31962:2;31950:9;31941:7;31937:23;31933:32;31930:119;;;31968:79;;:::i;:::-;31930:119;32088:1;32113:63;32168:7;32159:6;32148:9;32144:22;32113:63;:::i;:::-;32103:73;;32059:127;31844:349;;;;:::o

Swarm Source

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