APE Price: $0.67 (-1.21%)

Token

ByteMates Honorarys (BMH)

Overview

Max Total Supply

27 BMH

Holders

25

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 BMH
0x6f98e5ecb82d9efe928e9befdac5a3d1a3453fe5
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
BMH

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at apescan.io on 2025-02-07
*/

// File: erc721a/contracts/IERC721A.sol





// ERC721A Contracts v4.3.0

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



    /**

     * `_sequentialUpTo()` must be greater than `_startTokenId()`.

     */

    error SequentialUpToTooSmall();



    /**

     * The `tokenId` of a sequential mint exceeds `_sequentialUpTo()`.

     */

    error SequentialMintExceedsLimit();



    /**

     * Spot minting requires a `tokenId` greater than `_sequentialUpTo()`.

     */

    error SpotMintTokenIdTooSmall();



    /**

     * Cannot mint over a token that already exists.

     */

    error TokenAlreadyExists();



    /**

     * The feature is not compatible with spot mints.

     */

    error NotCompatibleWithSpotMints();



    // =============================================================

    //                            STRUCTS

    // =============================================================



    struct TokenOwnership {

        // The address of the owner.

        address addr;

        // Stores the start time of ownership with minimal overhead for tokenomics.

        uint64 startTimestamp;

        // Whether the token has been burned.

        bool burned;

        // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.

        uint24 extraData;

    }



    // =============================================================

    //                         TOKEN COUNTERS

    // =============================================================



    /**

     * @dev Returns the total number of tokens in existence.

     * Burned tokens will reduce the count.

     * To get the total number of tokens minted, please see {_totalMinted}.

     */

    function totalSupply() external view returns (uint256);



    // =============================================================

    //                            IERC165

    // =============================================================



    /**

     * @dev Returns true if this contract implements the interface defined by

     * `interfaceId`. See the corresponding

     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)

     * to learn more about how these ids are created.

     *

     * This function call must use less than 30000 gas.

     */

    function supportsInterface(bytes4 interfaceId) external view returns (bool);



    // =============================================================

    //                            IERC721

    // =============================================================



    /**

     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.

     */

    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);



    /**

     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.

     */

    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);



    /**

     * @dev Emitted when `owner` enables or disables

     * (`approved`) `operator` to manage all of its assets.

     */

    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);



    /**

     * @dev Returns the number of tokens in `owner`'s account.

     */

    function balanceOf(address owner) external view returns (uint256 balance);



    /**

     * @dev Returns the owner of the `tokenId` token.

     *

     * Requirements:

     *

     * - `tokenId` must exist.

     */

    function ownerOf(uint256 tokenId) external view returns (address owner);



    /**

     * @dev Safely transfers `tokenId` token from `from` to `to`,

     * checking first that contract recipients are aware of the ERC721 protocol

     * to prevent tokens from being forever locked.

     *

     * Requirements:

     *

     * - `from` cannot be the zero address.

     * - `to` cannot be the zero address.

     * - `tokenId` token must exist and be owned by `from`.

     * - If the caller is not `from`, it must be have been allowed to move

     * this token by either {approve} or {setApprovalForAll}.

     * - If `to` refers to a smart contract, it must implement

     * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.

     *

     * Emits a {Transfer} event.

     */

    function safeTransferFrom(

        address from,

        address to,

        uint256 tokenId,

        bytes calldata data

    ) external payable;



    /**

     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.

     */

    function safeTransferFrom(

        address from,

        address to,

        uint256 tokenId

    ) external payable;



    /**

     * @dev Transfers `tokenId` from `from` to `to`.

     *

     * WARNING: Usage of this method is discouraged, use {safeTransferFrom}

     * whenever possible.

     *

     * Requirements:

     *

     * - `from` cannot be the zero address.

     * - `to` cannot be the zero address.

     * - `tokenId` token must be owned by `from`.

     * - If the caller is not `from`, it must be approved to move this token

     * by either {approve} or {setApprovalForAll}.

     *

     * Emits a {Transfer} event.

     */

    function transferFrom(

        address from,

        address to,

        uint256 tokenId

    ) external payable;



    /**

     * @dev Gives permission to `to` to transfer `tokenId` token to another account.

     * The approval is cleared when the token is transferred.

     *

     * Only a single account can be approved at a time, so approving the

     * zero address clears previous approvals.

     *

     * Requirements:

     *

     * - The caller must own the token or be an approved operator.

     * - `tokenId` must exist.

     *

     * Emits an {Approval} event.

     */

    function approve(address to, uint256 tokenId) external payable;



    /**

     * @dev Approve or remove `operator` as an operator for the caller.

     * Operators can call {transferFrom} or {safeTransferFrom}

     * for any token owned by the caller.

     *

     * Requirements:

     *

     * - The `operator` cannot be the caller.

     *

     * Emits an {ApprovalForAll} event.

     */

    function setApprovalForAll(address operator, bool _approved) external;



    /**

     * @dev Returns the account approved for `tokenId` token.

     *

     * Requirements:

     *

     * - `tokenId` must exist.

     */

    function getApproved(uint256 tokenId) external view returns (address operator);



    /**

     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.

     *

     * See {setApprovalForAll}.

     */

    function isApprovedForAll(address owner, address operator) external view returns (bool);



    // =============================================================

    //                        IERC721Metadata

    // =============================================================



    /**

     * @dev Returns the token collection name.

     */

    function name() external view returns (string memory);



    /**

     * @dev Returns the token collection symbol.

     */

    function symbol() external view returns (string memory);



    /**

     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.

     */

    function tokenURI(uint256 tokenId) external view returns (string memory);



    // =============================================================

    //                           IERC2309

    // =============================================================



    /**

     * @dev Emitted when tokens in `fromTokenId` to `toTokenId`

     * (inclusive) is transferred from `from` to `to`, as defined in the

     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.

     *

     * See {_mintERC2309} for more details.

     */

    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);

}



// File: erc721a/contracts/ERC721A.sol





// ERC721A Contracts v4.3.0

// 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()`.

 *

 * The `_sequentialUpTo()` function can be overriden to enable spot mints

 * (i.e. non-consecutive mints) for `tokenId`s greater than `_sequentialUpTo()`.

 *

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



    // The amount of tokens minted above `_sequentialUpTo()`.

    // We call these spot mints (i.e. non-sequential mints).

    uint256 private _spotMinted;



    // =============================================================

    //                          CONSTRUCTOR

    // =============================================================



    constructor(string memory name_, string memory symbol_) {

        _name = name_;

        _symbol = symbol_;

        _currentIndex = _startTokenId();



        if (_sequentialUpTo() < _startTokenId()) _revert(SequentialUpToTooSmall.selector);

    }



    // =============================================================

    //                   TOKEN COUNTING OPERATIONS

    // =============================================================



    /**

     * @dev Returns the starting token ID for sequential mints.

     *

     * Override this function to change the starting token ID for sequential mints.

     *

     * Note: The value returned must never change after any tokens have been minted.

     */

    function _startTokenId() internal view virtual returns (uint256) {

        return 0;

    }



    /**

     * @dev Returns the maximum token ID (inclusive) for sequential mints.

     *

     * Override this function to return a value less than 2**256 - 1,

     * but greater than `_startTokenId()`, to enable spot (non-sequential) mints.

     *

     * Note: The value returned must never change after any tokens have been minted.

     */

    function _sequentialUpTo() internal view virtual returns (uint256) {

        return type(uint256).max;

    }



    /**

     * @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 result) {

        // Counter underflow is impossible as `_burnCounter` cannot be incremented

        // more than `_currentIndex + _spotMinted - _startTokenId()` times.

        unchecked {

            // With spot minting, the intermediate `result` can be temporarily negative,

            // and the computation must be unchecked.

            result = _currentIndex - _burnCounter - _startTokenId();

            if (_sequentialUpTo() != type(uint256).max) result += _spotMinted;

        }

    }



    /**

     * @dev Returns the total amount of tokens minted in the contract.

     */

    function _totalMinted() internal view virtual returns (uint256 result) {

        // Counter underflow is impossible as `_currentIndex` does not decrement,

        // and it is initialized to `_startTokenId()`.

        unchecked {

            result = _currentIndex - _startTokenId();

            if (_sequentialUpTo() != type(uint256).max) result += _spotMinted;

        }

    }



    /**

     * @dev Returns the total number of tokens burned.

     */

    function _totalBurned() internal view virtual returns (uint256) {

        return _burnCounter;

    }



    /**

     * @dev Returns the total number of tokens that are spot-minted.

     */

    function _totalSpotMinted() internal view virtual returns (uint256) {

        return _spotMinted;

    }



    // =============================================================

    //                    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.selector);

        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.selector);



        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 Returns whether the ownership slot at `index` is initialized.

     * An uninitialized slot does not necessarily mean that the slot has no owner.

     */

    function _ownershipIsInitialized(uint256 index) internal view virtual returns (bool) {

        return _packedOwnerships[index] != 0;

    }



    /**

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

        }

    }



    /**

     * @dev Returns the packed ownership data of `tokenId`.

     */

    function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) {

        if (_startTokenId() <= tokenId) {

            packed = _packedOwnerships[tokenId];



            if (tokenId > _sequentialUpTo()) {

                if (_packedOwnershipExists(packed)) return packed;

                _revert(OwnerQueryForNonexistentToken.selector);

            }



            // If the data at the starting slot does not exist, start the scan.

            if (packed == 0) {

                if (tokenId >= _currentIndex) _revert(OwnerQueryForNonexistentToken.selector);

                // 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, `tokenId` will not underflow.

                //

                // We can directly compare the packed value.

                // If the address is zero, packed will be zero.

                for (;;) {

                    unchecked {

                        packed = _packedOwnerships[--tokenId];

                    }

                    if (packed == 0) continue;

                    if (packed & _BITMASK_BURNED == 0) return packed;

                    // Otherwise, the token is burned, and we must revert.

                    // This handles the case of batch burned tokens, where only the burned bit

                    // of the starting slot is set, and remaining slots are left uninitialized.

                    _revert(OwnerQueryForNonexistentToken.selector);

                }

            }

            // Otherwise, the data exists and we can skip the scan.

            // This is possible because we have already achieved the target condition.

            // This saves 2143 gas on transfers of initialized tokens.

            // If the token is not burned, return `packed`. Otherwise, revert.

            if (packed & _BITMASK_BURNED == 0) return packed;

        }

        _revert(OwnerQueryForNonexistentToken.selector);

    }



    /**

     * @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. See {ERC721A-_approve}.

     *

     * Requirements:

     *

     * - The caller must own the token or be an approved operator.

     */

    function approve(address to, uint256 tokenId) public payable virtual override {

        _approve(to, tokenId, true);

    }



    /**

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



        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 result) {

        if (_startTokenId() <= tokenId) {

            if (tokenId > _sequentialUpTo()) return _packedOwnershipExists(_packedOwnerships[tokenId]);



            if (tokenId < _currentIndex) {

                uint256 packed;

                while ((packed = _packedOwnerships[tokenId]) == 0) --tokenId;

                result = packed & _BITMASK_BURNED == 0;

            }

        }

    }



    /**

     * @dev Returns whether `packed` represents a token that exists.

     */

    function _packedOwnershipExists(uint256 packed) private pure returns (bool result) {

        assembly {

            // The following is equivalent to `owner != address(0) && burned == false`.

            // Symbolically tested.

            result := gt(and(packed, _BITMASK_ADDRESS), and(packed, _BITMASK_BURNED))

        }

    }



    /**

     * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.

     */

    function _isSenderApprovedOrOwner(

        address approvedAddress,

        address owner,

        address msgSender

    ) private pure returns (bool result) {

        assembly {

            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.

            owner := and(owner, _BITMASK_ADDRESS)

            // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.

            msgSender := and(msgSender, _BITMASK_ADDRESS)

            // `msgSender == owner || msgSender == approvedAddress`.

            result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))

        }

    }



    /**

     * @dev Returns the storage slot and value for the approved address of `tokenId`.

     */

    function _getApprovedSlotAndAddress(uint256 tokenId)

        private

        view

        returns (uint256 approvedAddressSlot, address approvedAddress)

    {

        TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];

        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`.

        assembly {

            approvedAddressSlot := tokenApproval.slot

            approvedAddress := sload(approvedAddressSlot)

        }

    }



    // =============================================================

    //                      TRANSFER OPERATIONS

    // =============================================================



    /**

     * @dev Transfers `tokenId` from `from` to `to`.

     *

     * Requirements:

     *

     * - `from` cannot be the zero address.

     * - `to` cannot be the zero address.

     * - `tokenId` token must be owned by `from`.

     * - If the caller is not `from`, it must be approved to move this token

     * by either {approve} or {setApprovalForAll}.

     *

     * Emits a {Transfer} event.

     */

    function transferFrom(

        address from,

        address to,

        uint256 tokenId

    ) public payable virtual override {

        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);



        // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean.

        from = address(uint160(uint256(uint160(from)) & _BITMASK_ADDRESS));



        if (address(uint160(prevOwnershipPacked)) != from) _revert(TransferFromIncorrectOwner.selector);



        (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.selector);



        _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;

                    }

                }

            }

        }



        // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.

        uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;

        assembly {

            // 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.

                from, // `from`.

                toMasked, // `to`.

                tokenId // `tokenId`.

            )

        }

        if (toMasked == 0) _revert(TransferToZeroAddress.selector);



        _afterTokenTransfers(from, to, tokenId, 1);

    }



    /**

     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.

     */

    function safeTransferFrom(

        address from,

        address to,

        uint256 tokenId

    ) public payable virtual override {

        safeTransferFrom(from, to, tokenId, '');

    }



    /**

     * @dev Safely transfers `tokenId` token from `from` to `to`.

     *

     * Requirements:

     *

     * - `from` cannot be the zero address.

     * - `to` cannot be the zero address.

     * - `tokenId` token must exist and be owned by `from`.

     * - If the caller is not `from`, it must be approved to move this token

     * by either {approve} or {setApprovalForAll}.

     * - If `to` refers to a smart contract, it must implement

     * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.

     *

     * Emits a {Transfer} event.

     */

    function safeTransferFrom(

        address from,

        address to,

        uint256 tokenId,

        bytes memory _data

    ) public payable virtual override {

        transferFrom(from, to, tokenId);

        if (to.code.length != 0)

            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {

                _revert(TransferToNonERC721ReceiverImplementer.selector);

            }

    }



    /**

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

            }

            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.selector);



        _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:

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

            );



            // Updates:

            // - `balance += quantity`.

            // - `numberMinted += quantity`.

            //

            // We can directly add to the `balance` and `numberMinted`.

            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);



            // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.

            uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;



            if (toMasked == 0) _revert(MintToZeroAddress.selector);



            uint256 end = startTokenId + quantity;

            uint256 tokenId = startTokenId;



            if (end - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector);



            do {

                assembly {

                    // 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`.

                        tokenId // `tokenId`.

                    )

                }

                // The `!=` check ensures that large values of `quantity`

                // that overflows uint256 will make the loop run out of gas.

            } while (++tokenId != end);



            _currentIndex = end;

        }

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

    }



    /**

     * @dev Mints `quantity` tokens and transfers them to `to`.

     *

     * This function is intended for efficient minting only during contract creation.

     *

     * It emits only one {ConsecutiveTransfer} as defined in

     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),

     * instead of a sequence of {Transfer} event(s).

     *

     * Calling this function outside of contract creation WILL make your contract

     * non-compliant with the ERC721 standard.

     * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309

     * {ConsecutiveTransfer} event is only permissible during contract creation.

     *

     * Requirements:

     *

     * - `to` cannot be the zero address.

     * - `quantity` must be greater than 0.

     *

     * Emits a {ConsecutiveTransfer} event.

     */

    function _mintERC2309(address to, uint256 quantity) internal virtual {

        uint256 startTokenId = _currentIndex;

        if (to == address(0)) _revert(MintToZeroAddress.selector);

        if (quantity == 0) _revert(MintZeroQuantity.selector);

        if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) _revert(MintERC2309QuantityExceedsLimit.selector);



        _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)

            );



            if (startTokenId + quantity - 1 > _sequentialUpTo()) _revert(SequentialMintExceedsLimit.selector);



            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.selector);

                    }

                } while (index < end);

                // This prevents reentrancy to `_safeMint`.

                // It does not prevent reentrancy to `_safeMintSpot`.

                if (_currentIndex != end) revert();

            }

        }

    }



    /**

     * @dev Equivalent to `_safeMint(to, quantity, '')`.

     */

    function _safeMint(address to, uint256 quantity) internal virtual {

        _safeMint(to, quantity, '');

    }



    /**

     * @dev Mints a single token at `tokenId`.

     *

     * Note: A spot-minted `tokenId` that has been burned can be re-minted again.

     *

     * Requirements:

     *

     * - `to` cannot be the zero address.

     * - `tokenId` must be greater than `_sequentialUpTo()`.

     * - `tokenId` must not exist.

     *

     * Emits a {Transfer} event for each mint.

     */

    function _mintSpot(address to, uint256 tokenId) internal virtual {

        if (tokenId <= _sequentialUpTo()) _revert(SpotMintTokenIdTooSmall.selector);

        uint256 prevOwnershipPacked = _packedOwnerships[tokenId];

        if (_packedOwnershipExists(prevOwnershipPacked)) _revert(TokenAlreadyExists.selector);



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



        // Overflows are incredibly unrealistic.

        // The `numberMinted` for `to` is incremented by 1, and has a max limit of 2**64 - 1.

        // `_spotMinted` is incremented by 1, and has a max limit of 2**256 - 1.

        unchecked {

            // Updates:

            // - `address` to the owner.

            // - `startTimestamp` to the timestamp of minting.

            // - `burned` to `false`.

            // - `nextInitialized` to `true` (as `quantity == 1`).

            _packedOwnerships[tokenId] = _packOwnershipData(

                to,

                _nextInitializedFlag(1) | _nextExtraData(address(0), to, prevOwnershipPacked)

            );



            // Updates:

            // - `balance += 1`.

            // - `numberMinted += 1`.

            //

            // We can directly add to the `balance` and `numberMinted`.

            _packedAddressData[to] += (1 << _BITPOS_NUMBER_MINTED) | 1;



            // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.

            uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;



            if (toMasked == 0) _revert(MintToZeroAddress.selector);



            assembly {

                // 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`.

                    tokenId // `tokenId`.

                )

            }



            ++_spotMinted;

        }



        _afterTokenTransfers(address(0), to, tokenId, 1);

    }



    /**

     * @dev Safely mints a single token at `tokenId`.

     *

     * Note: A spot-minted `tokenId` that has been burned can be re-minted again.

     *

     * Requirements:

     *

     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}.

     * - `tokenId` must be greater than `_sequentialUpTo()`.

     * - `tokenId` must not exist.

     *

     * See {_mintSpot}.

     *

     * Emits a {Transfer} event.

     */

    function _safeMintSpot(

        address to,

        uint256 tokenId,

        bytes memory _data

    ) internal virtual {

        _mintSpot(to, tokenId);



        unchecked {

            if (to.code.length != 0) {

                uint256 currentSpotMinted = _spotMinted;

                if (!_checkContractOnERC721Received(address(0), to, tokenId, _data)) {

                    _revert(TransferToNonERC721ReceiverImplementer.selector);

                }

                // This prevents reentrancy to `_safeMintSpot`.

                // It does not prevent reentrancy to `_safeMint`.

                if (_spotMinted != currentSpotMinted) revert();

            }

        }

    }



    /**

     * @dev Equivalent to `_safeMintSpot(to, tokenId, '')`.

     */

    function _safeMintSpot(address to, uint256 tokenId) internal virtual {

        _safeMintSpot(to, tokenId, '');

    }



    // =============================================================

    //                       APPROVAL OPERATIONS

    // =============================================================



    /**

     * @dev Equivalent to `_approve(to, tokenId, false)`.

     */

    function _approve(address to, uint256 tokenId) internal virtual {

        _approve(to, tokenId, false);

    }



    /**

     * @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:

     *

     * - `tokenId` must exist.

     *

     * Emits an {Approval} event.

     */

    function _approve(

        address to,

        uint256 tokenId,

        bool approvalCheck

    ) internal virtual {

        address owner = ownerOf(tokenId);



        if (approvalCheck && _msgSenderERC721A() != owner)

            if (!isApprovedForAll(owner, _msgSenderERC721A())) {

                _revert(ApprovalCallerNotOwnerNorApproved.selector);

            }



        _tokenApprovals[tokenId].value = to;

        emit Approval(owner, to, tokenId);

    }



    // =============================================================

    //                        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.selector);

        }



        _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 + _spotMinted` 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.selector);

        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)

        }

    }



    /**

     * @dev For more efficient reverts.

     */

    function _revert(bytes4 errorSelector) internal pure {

        assembly {

            mstore(0x00, errorSelector)

            revert(0x00, 0x04)

        }

    }

}



// File: @openzeppelin/contracts/security/ReentrancyGuard.sol





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



pragma solidity ^0.8.0;



/**

 * @dev Contract module that helps prevent reentrant calls to a function.

 *

 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier

 * available, which can be applied to functions to make sure there are no nested

 * (reentrant) calls to them.

 *

 * Note that because there is a single `nonReentrant` guard, functions marked as

 * `nonReentrant` may not call one another. This can be worked around by making

 * those functions `private`, and then adding `external` `nonReentrant` entry

 * points to them.

 *

 * TIP: If you would like to learn more about reentrancy and alternative ways

 * to protect against it, check out our blog post

 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].

 */

abstract contract ReentrancyGuard {

    // Booleans are more expensive than uint256 or any type that takes up a full

    // word because each write operation emits an extra SLOAD to first read the

    // slot's contents, replace the bits taken up by the boolean, and then write

    // back. This is the compiler's defense against contract upgrades and

    // pointer aliasing, and it cannot be disabled.



    // The values being non-zero value makes deployment a bit more expensive,

    // but in exchange the refund on every call to nonReentrant will be lower in

    // amount. Since refunds are capped to a percentage of the total

    // transaction's gas, it is best to keep them low in cases like this one, to

    // increase the likelihood of the full refund coming into effect.

    uint256 private constant _NOT_ENTERED = 1;

    uint256 private constant _ENTERED = 2;



    uint256 private _status;



    constructor() {

        _status = _NOT_ENTERED;

    }



    /**

     * @dev Prevents a contract from calling itself, directly or indirectly.

     * Calling a `nonReentrant` function from another `nonReentrant`

     * function is not supported. It is possible to prevent this from happening

     * by making the `nonReentrant` function external, and making it call a

     * `private` function that does the actual work.

     */

    modifier nonReentrant() {

        _nonReentrantBefore();

        _;

        _nonReentrantAfter();

    }



    function _nonReentrantBefore() private {

        // On the first call to nonReentrant, _status will be _NOT_ENTERED

        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");



        // Any calls to nonReentrant after this point will fail

        _status = _ENTERED;

    }



    function _nonReentrantAfter() private {

        // By storing the original value once again, a refund is triggered (see

        // https://eips.ethereum.org/EIPS/eip-2200)

        _status = _NOT_ENTERED;

    }



    /**

     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a

     * `nonReentrant` function in the call stack.

     */

    function _reentrancyGuardEntered() internal view returns (bool) {

        return _status == _ENTERED;

    }

}



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





// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)



pragma solidity ^0.8.20;



/**

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

    }



    function _contextSuffixLength() internal view virtual returns (uint256) {

        return 0;

    }

}



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





// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)



pragma solidity ^0.8.20;





/**

 * @dev Contract module which provides a basic access control mechanism, where

 * there is an account (an owner) that can be granted exclusive access to

 * specific functions.

 *

 * The initial owner is set to the address provided by the deployer. This can

 * later be changed with {transferOwnership}.

 *

 * This module is used through inheritance. It will make available the modifier

 * `onlyOwner`, which can be applied to your functions to restrict their use to

 * the owner.

 */

abstract contract Ownable is Context {

    address private _owner;



    /**

     * @dev The caller account is not authorized to perform an operation.

     */

    error OwnableUnauthorizedAccount(address account);



    /**

     * @dev The owner is not a valid owner account. (eg. `address(0)`)

     */

    error OwnableInvalidOwner(address owner);



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



    /**

     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.

     */

    constructor(address initialOwner) {

        if (initialOwner == address(0)) {

            revert OwnableInvalidOwner(address(0));

        }

        _transferOwnership(initialOwner);

    }



    /**

     * @dev Throws if called by any account other than the owner.

     */

    modifier onlyOwner() {

        _checkOwner();

        _;

    }



    /**

     * @dev Returns the address of the current owner.

     */

    function owner() public view virtual returns (address) {

        return _owner;

    }



    /**

     * @dev Throws if the sender is not the owner.

     */

    function _checkOwner() internal view virtual {

        if (owner() != _msgSender()) {

            revert OwnableUnauthorizedAccount(_msgSender());

        }

    }



    /**

     * @dev Leaves the contract without owner. It will not be possible to call

     * `onlyOwner` functions. Can only be called by the current owner.

     *

     * NOTE: Renouncing ownership will leave the contract without an owner,

     * thereby disabling any functionality that is only available to the owner.

     */

    function renounceOwnership() public virtual onlyOwner {

        _transferOwnership(address(0));

    }



    /**

     * @dev Transfers ownership of the contract to a new account (`newOwner`).

     * Can only be called by the current owner.

     */

    function transferOwnership(address newOwner) public virtual onlyOwner {

        if (newOwner == address(0)) {

            revert OwnableInvalidOwner(address(0));

        }

        _transferOwnership(newOwner);

    }



    /**

     * @dev Transfers ownership of the contract to a new account (`newOwner`).

     * Internal function without access restriction.

     */

    function _transferOwnership(address newOwner) internal virtual {

        address oldOwner = _owner;

        _owner = newOwner;

        emit OwnershipTransferred(oldOwner, newOwner);

    }

}



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





// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)



pragma solidity ^0.8.20;



/**

 * @dev Standard math utilities missing in the Solidity language.

 */

library Math {

    /**

     * @dev Muldiv operation overflow.

     */

    error MathOverflowedMulDiv();



    enum Rounding {

        Floor, // Toward negative infinity

        Ceil, // Toward positive infinity

        Trunc, // Toward zero

        Expand // Away from zero

    }



    /**

     * @dev Returns the addition of two unsigned integers, with an overflow flag.

     */

    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {

        unchecked {

            uint256 c = a + b;

            if (c < a) return (false, 0);

            return (true, c);

        }

    }



    /**

     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.

     */

    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {

        unchecked {

            if (b > a) return (false, 0);

            return (true, a - b);

        }

    }



    /**

     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.

     */

    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {

        unchecked {

            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the

            // benefit is lost if 'b' is also tested.

            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522

            if (a == 0) return (true, 0);

            uint256 c = a * b;

            if (c / a != b) return (false, 0);

            return (true, c);

        }

    }



    /**

     * @dev Returns the division of two unsigned integers, with a division by zero flag.

     */

    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {

        unchecked {

            if (b == 0) return (false, 0);

            return (true, a / b);

        }

    }



    /**

     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.

     */

    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {

        unchecked {

            if (b == 0) return (false, 0);

            return (true, a % b);

        }

    }



    /**

     * @dev Returns the largest of two numbers.

     */

    function max(uint256 a, uint256 b) internal pure returns (uint256) {

        return a > b ? a : b;

    }



    /**

     * @dev Returns the smallest of two numbers.

     */

    function min(uint256 a, uint256 b) internal pure returns (uint256) {

        return a < b ? a : b;

    }



    /**

     * @dev Returns the average of two numbers. The result is rounded towards

     * zero.

     */

    function average(uint256 a, uint256 b) internal pure returns (uint256) {

        // (a + b) / 2 can overflow.

        return (a & b) + (a ^ b) / 2;

    }



    /**

     * @dev Returns the ceiling of the division of two numbers.

     *

     * This differs from standard division with `/` in that it rounds towards infinity instead

     * of rounding towards zero.

     */

    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {

        if (b == 0) {

            // Guarantee the same behavior as in a regular Solidity division.

            return a / b;

        }



        // (a + b - 1) / b can overflow on addition, so we distribute.

        return a == 0 ? 0 : (a - 1) / b + 1;

    }



    /**

     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or

     * denominator == 0.

     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by

     * Uniswap Labs also under MIT license.

     */

    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {

        unchecked {

            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use

            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256

            // variables such that product = prod1 * 2^256 + prod0.

            uint256 prod0 = x * y; // Least significant 256 bits of the product

            uint256 prod1; // Most significant 256 bits of the product

            assembly {

                let mm := mulmod(x, y, not(0))

                prod1 := sub(sub(mm, prod0), lt(mm, prod0))

            }



            // Handle non-overflow cases, 256 by 256 division.

            if (prod1 == 0) {

                // Solidity will revert if denominator == 0, unlike the div opcode on its own.

                // The surrounding unchecked block does not change this fact.

                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.

                return prod0 / denominator;

            }



            // Make sure the result is less than 2^256. Also prevents denominator == 0.

            if (denominator <= prod1) {

                revert MathOverflowedMulDiv();

            }



            ///////////////////////////////////////////////

            // 512 by 256 division.

            ///////////////////////////////////////////////



            // Make division exact by subtracting the remainder from [prod1 prod0].

            uint256 remainder;

            assembly {

                // Compute remainder using mulmod.

                remainder := mulmod(x, y, denominator)



                // Subtract 256 bit number from 512 bit number.

                prod1 := sub(prod1, gt(remainder, prod0))

                prod0 := sub(prod0, remainder)

            }



            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.

            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.



            uint256 twos = denominator & (0 - denominator);

            assembly {

                // Divide denominator by twos.

                denominator := div(denominator, twos)



                // Divide [prod1 prod0] by twos.

                prod0 := div(prod0, twos)



                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.

                twos := add(div(sub(0, twos), twos), 1)

            }



            // Shift in bits from prod1 into prod0.

            prod0 |= prod1 * twos;



            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such

            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for

            // four bits. That is, denominator * inv = 1 mod 2^4.

            uint256 inverse = (3 * denominator) ^ 2;



            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also

            // works in modular arithmetic, doubling the correct bits in each step.

            inverse *= 2 - denominator * inverse; // inverse mod 2^8

            inverse *= 2 - denominator * inverse; // inverse mod 2^16

            inverse *= 2 - denominator * inverse; // inverse mod 2^32

            inverse *= 2 - denominator * inverse; // inverse mod 2^64

            inverse *= 2 - denominator * inverse; // inverse mod 2^128

            inverse *= 2 - denominator * inverse; // inverse mod 2^256



            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.

            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is

            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1

            // is no longer required.

            result = prod0 * inverse;

            return result;

        }

    }



    /**

     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.

     */

    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {

        uint256 result = mulDiv(x, y, denominator);

        if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {

            result += 1;

        }

        return result;

    }



    /**

     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded

     * towards zero.

     *

     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).

     */

    function sqrt(uint256 a) internal pure returns (uint256) {

        if (a == 0) {

            return 0;

        }



        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.

        //

        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have

        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.

        //

        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`

        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`

        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`

        //

        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.

        uint256 result = 1 << (log2(a) >> 1);



        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,

        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at

        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision

        // into the expected uint128 result.

        unchecked {

            result = (result + a / result) >> 1;

            result = (result + a / result) >> 1;

            result = (result + a / result) >> 1;

            result = (result + a / result) >> 1;

            result = (result + a / result) >> 1;

            result = (result + a / result) >> 1;

            result = (result + a / result) >> 1;

            return min(result, a / result);

        }

    }



    /**

     * @notice Calculates sqrt(a), following the selected rounding direction.

     */

    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {

        unchecked {

            uint256 result = sqrt(a);

            return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);

        }

    }



    /**

     * @dev Return the log in base 2 of a positive value rounded towards zero.

     * Returns 0 if given 0.

     */

    function log2(uint256 value) internal pure returns (uint256) {

        uint256 result = 0;

        unchecked {

            if (value >> 128 > 0) {

                value >>= 128;

                result += 128;

            }

            if (value >> 64 > 0) {

                value >>= 64;

                result += 64;

            }

            if (value >> 32 > 0) {

                value >>= 32;

                result += 32;

            }

            if (value >> 16 > 0) {

                value >>= 16;

                result += 16;

            }

            if (value >> 8 > 0) {

                value >>= 8;

                result += 8;

            }

            if (value >> 4 > 0) {

                value >>= 4;

                result += 4;

            }

            if (value >> 2 > 0) {

                value >>= 2;

                result += 2;

            }

            if (value >> 1 > 0) {

                result += 1;

            }

        }

        return result;

    }



    /**

     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.

     * Returns 0 if given 0.

     */

    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {

        unchecked {

            uint256 result = log2(value);

            return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);

        }

    }



    /**

     * @dev Return the log in base 10 of a positive value rounded towards zero.

     * Returns 0 if given 0.

     */

    function log10(uint256 value) internal pure returns (uint256) {

        uint256 result = 0;

        unchecked {

            if (value >= 10 ** 64) {

                value /= 10 ** 64;

                result += 64;

            }

            if (value >= 10 ** 32) {

                value /= 10 ** 32;

                result += 32;

            }

            if (value >= 10 ** 16) {

                value /= 10 ** 16;

                result += 16;

            }

            if (value >= 10 ** 8) {

                value /= 10 ** 8;

                result += 8;

            }

            if (value >= 10 ** 4) {

                value /= 10 ** 4;

                result += 4;

            }

            if (value >= 10 ** 2) {

                value /= 10 ** 2;

                result += 2;

            }

            if (value >= 10 ** 1) {

                result += 1;

            }

        }

        return result;

    }



    /**

     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.

     * Returns 0 if given 0.

     */

    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {

        unchecked {

            uint256 result = log10(value);

            return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);

        }

    }



    /**

     * @dev Return the log in base 256 of a positive value rounded towards zero.

     * Returns 0 if given 0.

     *

     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.

     */

    function log256(uint256 value) internal pure returns (uint256) {

        uint256 result = 0;

        unchecked {

            if (value >> 128 > 0) {

                value >>= 128;

                result += 16;

            }

            if (value >> 64 > 0) {

                value >>= 64;

                result += 8;

            }

            if (value >> 32 > 0) {

                value >>= 32;

                result += 4;

            }

            if (value >> 16 > 0) {

                value >>= 16;

                result += 2;

            }

            if (value >> 8 > 0) {

                result += 1;

            }

        }

        return result;

    }



    /**

     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.

     * Returns 0 if given 0.

     */

    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {

        unchecked {

            uint256 result = log256(value);

            return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);

        }

    }



    /**

     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.

     */

    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {

        return uint8(rounding) % 2 == 1;

    }

}



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





// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)



pragma solidity ^0.8.20;



/**

 * @dev Standard signed math utilities missing in the Solidity language.

 */

library SignedMath {

    /**

     * @dev Returns the largest of two signed numbers.

     */

    function max(int256 a, int256 b) internal pure returns (int256) {

        return a > b ? a : b;

    }



    /**

     * @dev Returns the smallest of two signed numbers.

     */

    function min(int256 a, int256 b) internal pure returns (int256) {

        return a < b ? a : b;

    }



    /**

     * @dev Returns the average of two signed numbers without overflow.

     * The result is rounded towards zero.

     */

    function average(int256 a, int256 b) internal pure returns (int256) {

        // Formula from the book "Hacker's Delight"

        int256 x = (a & b) + ((a ^ b) >> 1);

        return x + (int256(uint256(x) >> 255) & (a ^ b));

    }



    /**

     * @dev Returns the absolute unsigned value of a signed value.

     */

    function abs(int256 n) internal pure returns (uint256) {

        unchecked {

            // must be unchecked in order to support `n = type(int256).min`

            return uint256(n >= 0 ? n : -n);

        }

    }

}



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





// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)



pragma solidity ^0.8.20;







/**

 * @dev String operations.

 */

library Strings {

    bytes16 private constant HEX_DIGITS = "0123456789abcdef";

    uint8 private constant ADDRESS_LENGTH = 20;



    /**

     * @dev The `value` string doesn't fit in the specified `length`.

     */

    error StringsInsufficientHexLength(uint256 value, uint256 length);



    /**

     * @dev Converts a `uint256` to its ASCII `string` decimal representation.

     */

    function toString(uint256 value) internal pure returns (string memory) {

        unchecked {

            uint256 length = Math.log10(value) + 1;

            string memory buffer = new string(length);

            uint256 ptr;

            /// @solidity memory-safe-assembly

            assembly {

                ptr := add(buffer, add(32, length))

            }

            while (true) {

                ptr--;

                /// @solidity memory-safe-assembly

                assembly {

                    mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))

                }

                value /= 10;

                if (value == 0) break;

            }

            return buffer;

        }

    }



    /**

     * @dev Converts a `int256` to its ASCII `string` decimal representation.

     */

    function toStringSigned(int256 value) internal pure returns (string memory) {

        return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));

    }



    /**

     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.

     */

    function toHexString(uint256 value) internal pure returns (string memory) {

        unchecked {

            return toHexString(value, Math.log256(value) + 1);

        }

    }



    /**

     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.

     */

    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {

        uint256 localValue = value;

        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_DIGITS[localValue & 0xf];

            localValue >>= 4;

        }

        if (localValue != 0) {

            revert StringsInsufficientHexLength(value, length);

        }

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

    }



    /**

     * @dev Returns true if the two strings are equal.

     */

    function equal(string memory a, string memory b) internal pure returns (bool) {

        return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));

    }

}



// File: contracts/ByteMates.sol







pragma solidity >=0.8.4 <0.9.1;













contract BMH is ERC721A, Ownable, ReentrancyGuard {



constructor() ERC721A("ByteMates Honorarys ","BMH") Ownable(msg.sender) {}

 

  using Strings for uint256;

  string public uriBase = "ipfs://cid/";

  string public uriExtension = ".json";



  function airDropSolo(uint256 _mintAmount, address _receiver) public onlyOwner {

    _safeMint(_receiver, _mintAmount);

  }



  function airDropMulti(address[] calldata to, uint _mintAmount) public onlyOwner {       

     for (uint i = 0; i < to.length; i++) {   

     _safeMint(to[i], _mintAmount);

    }

  }  



  function _baseURI() internal view virtual override returns (string memory) {

    return uriBase;

  }

 

  function _startTokenId() internal view virtual override returns (uint256) {

    return 1;

  }



  function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {

    require(_exists(_tokenId), "Does not exist");

    string memory currentBaseURI = _baseURI();

    return bytes(currentBaseURI).length > 0

        ? string(abi.encodePacked(currentBaseURI, _tokenId.toString(), uriExtension))

        : '';

  }



  function setUriBase(string memory _uriBase) public onlyOwner {

    uriBase = _uriBase;

  }



  function setUriExtension(string memory _uriExtension) public onlyOwner {

    uriExtension = _uriExtension;

  }





  function withdraw() public onlyOwner nonReentrant returns(bool os){

        (os,) = payable(owner()).call{value: address(this).balance}('');

        return(os);

    }



}

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":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"NotCompatibleWithSpotMints","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"SequentialMintExceedsLimit","type":"error"},{"inputs":[],"name":"SequentialUpToTooSmall","type":"error"},{"inputs":[],"name":"SpotMintTokenIdTooSmall","type":"error"},{"inputs":[],"name":"TokenAlreadyExists","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address[]","name":"to","type":"address[]"},{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"airDropMulti","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"airDropSolo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriBase","type":"string"}],"name":"setUriBase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriExtension","type":"string"}],"name":"setUriExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uriBase","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uriExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[{"internalType":"bool","name":"os","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

60806040526040518060400160405280600b81526020017f697066733a2f2f6369642f000000000000000000000000000000000000000000815250600b90816200004a919062000578565b506040518060400160405280600581526020017f2e6a736f6e000000000000000000000000000000000000000000000000000000815250600c908162000091919062000578565b503480156200009e575f80fd5b50336040518060400160405280601481526020017f427974654d6174657320486f6e6f7261727973200000000000000000000000008152506040518060400160405280600381526020017f424d48000000000000000000000000000000000000000000000000000000000081525081600290816200011d919062000578565b5080600390816200012f919062000578565b50620001406200021a60201b60201c565b5f81905550620001556200021a60201b60201c565b620001656200022260201b60201c565b101562000185576200018463fed8210f60e01b6200024960201b60201c565b5b50505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620001fa575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401620001f191906200069f565b60405180910390fd5b6200020b816200025160201b60201c565b506001600a81905550620006ba565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b805f5260045ffd5b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200039057607f821691505b602082108103620003a657620003a56200034b565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026200040a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620003cd565b620004168683620003cd565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f620004606200045a62000454846200042e565b62000437565b6200042e565b9050919050565b5f819050919050565b6200047b8362000440565b620004936200048a8262000467565b848454620003d9565b825550505050565b5f90565b620004a96200049b565b620004b681848462000470565b505050565b5b81811015620004dd57620004d15f826200049f565b600181019050620004bc565b5050565b601f8211156200052c57620004f681620003ac565b6200050184620003be565b8101602085101562000511578190505b620005296200052085620003be565b830182620004bb565b50505b505050565b5f82821c905092915050565b5f6200054e5f198460080262000531565b1980831691505092915050565b5f6200056883836200053d565b9150826002028217905092915050565b620005838262000314565b67ffffffffffffffff8111156200059f576200059e6200031e565b5b620005ab825462000378565b620005b8828285620004e1565b5f60209050601f831160018114620005ee575f8415620005d9578287015190505b620005e585826200055b565b86555062000654565b601f198416620005fe86620003ac565b5f5b82811015620006275784890151825560018201915060208501945060208101905062000600565b8683101562000647578489015162000643601f8916826200053d565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f62000687826200065c565b9050919050565b62000699816200067b565b82525050565b5f602082019050620006b45f8301846200068e565b92915050565b612aa280620006c85f395ff3fe60806040526004361061014a575f3560e01c806370a08231116100b5578063a22cb4651161006e578063a22cb46514610444578063b88d4fde1461046c578063c87b56dd14610488578063e985e9c5146104c4578063f2fde38b14610500578063fbca0ce1146105285761014a565b806370a082311461034e578063715018a61461038a578063751a144d146103a05780638da5cb5b146103c8578063951be370146103f257806395d89b411461041a5761014a565b806327fc0cff1161010757806327fc0cff146102525780632ce9af501461027a5780633ccfd60b146102a257806342842e0e146102cc57806352ee4696146102e85780636352211e146103125761014a565b806301ffc9a71461014e57806306fdde031461018a578063081812fc146101b4578063095ea7b3146101f057806318160ddd1461020c57806323b872dd14610236575b5f80fd5b348015610159575f80fd5b50610174600480360381019061016f9190611ce0565b610552565b6040516101819190611d25565b60405180910390f35b348015610195575f80fd5b5061019e6105e3565b6040516101ab9190611dc8565b60405180910390f35b3480156101bf575f80fd5b506101da60048036038101906101d59190611e1b565b610673565b6040516101e79190611e85565b60405180910390f35b61020a60048036038101906102059190611ec8565b6106cc565b005b348015610217575f80fd5b506102206106dc565b60405161022d9190611f15565b60405180910390f35b610250600480360381019061024b9190611f2e565b610727565b005b34801561025d575f80fd5b50610278600480360381019061027391906120aa565b6109d2565b005b348015610285575f80fd5b506102a0600480360381019061029b91906120aa565b6109ed565b005b3480156102ad575f80fd5b506102b6610a08565b6040516102c39190611d25565b60405180910390f35b6102e660048036038101906102e19190611f2e565b610a94565b005b3480156102f3575f80fd5b506102fc610ab3565b6040516103099190611dc8565b60405180910390f35b34801561031d575f80fd5b5061033860048036038101906103339190611e1b565b610b3f565b6040516103459190611e85565b60405180910390f35b348015610359575f80fd5b50610374600480360381019061036f91906120f1565b610b50565b6040516103819190611f15565b60405180910390f35b348015610395575f80fd5b5061039e610be4565b005b3480156103ab575f80fd5b506103c660048036038101906103c19190612179565b610bf7565b005b3480156103d3575f80fd5b506103dc610c56565b6040516103e99190611e85565b60405180910390f35b3480156103fd575f80fd5b50610418600480360381019061041391906121d6565b610c7e565b005b348015610425575f80fd5b5061042e610c94565b60405161043b9190611dc8565b60405180910390f35b34801561044f575f80fd5b5061046a6004803603810190610465919061223e565b610d24565b005b6104866004803603810190610481919061231a565b610e2a565b005b348015610493575f80fd5b506104ae60048036038101906104a99190611e1b565b610e7b565b6040516104bb9190611dc8565b60405180910390f35b3480156104cf575f80fd5b506104ea60048036038101906104e5919061239a565b610f22565b6040516104f79190611d25565b60405180910390f35b34801561050b575f80fd5b50610526600480360381019061052191906120f1565b610fb0565b005b348015610533575f80fd5b5061053c611034565b6040516105499190611dc8565b60405180910390f35b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806105ac57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806105dc5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546105f290612405565b80601f016020809104026020016040519081016040528092919081815260200182805461061e90612405565b80156106695780601f1061064057610100808354040283529160200191610669565b820191905f5260205f20905b81548152906001019060200180831161064c57829003601f168201915b5050505050905090565b5f61067d826110c0565b6106925761069163cf4700e460e01b611163565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6106d88282600161116b565b5050565b5f6106e5611295565b6001545f54030390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61071761129d565b1461072457600854810190505b90565b5f610731826112c4565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146107a6576107a563a114810060e01b611163565b5b5f806107b1846113d3565b915091506107c781876107c26113f6565b6113fd565b6107f2576107dc866107d76113f6565b610f22565b6107f1576107f06359c896be60e01b611163565b5b5b6107ff8686866001611440565b8015610809575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600101919050819055506108d1856108ad888887611446565b7c02000000000000000000000000000000000000000000000000000000001761146d565b60045f8681526020019081526020015f20819055505f7c020000000000000000000000000000000000000000000000000000000084160361094d575f6001850190505f60045f8381526020019081526020015f20540361094b575f54811461094a578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f81036109bc576109bb63ea553b3460e01b611163565b5b6109c98787876001611497565b50505050505050565b6109da61149d565b80600b90816109e991906125d2565b5050565b6109f561149d565b80600c9081610a0491906125d2565b5050565b5f610a1161149d565b610a19611524565b610a21610c56565b73ffffffffffffffffffffffffffffffffffffffff1647604051610a44906126ce565b5f6040518083038185875af1925050503d805f8114610a7e576040519150601f19603f3d011682016040523d82523d5f602084013e610a83565b606091505b505080915050610a91611573565b90565b610aae83838360405180602001604052805f815250610e2a565b505050565b600c8054610ac090612405565b80601f0160208091040260200160405190810160405280929190818152602001828054610aec90612405565b8015610b375780601f10610b0e57610100808354040283529160200191610b37565b820191905f5260205f20905b815481529060010190602001808311610b1a57829003601f168201915b505050505081565b5f610b49826112c4565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610b9557610b94638f4eb60460e01b611163565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b610bec61149d565b610bf55f61157d565b565b610bff61149d565b5f5b83839050811015610c5057610c3d848483818110610c2257610c216126e2565b5b9050602002016020810190610c3791906120f1565b83611640565b8080610c489061273c565b915050610c01565b50505050565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610c8661149d565b610c908183611640565b5050565b606060038054610ca390612405565b80601f0160208091040260200160405190810160405280929190818152602001828054610ccf90612405565b8015610d1a5780601f10610cf157610100808354040283529160200191610d1a565b820191905f5260205f20905b815481529060010190602001808311610cfd57829003601f168201915b5050505050905090565b8060075f610d306113f6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16610dd96113f6565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610e1e9190611d25565b60405180910390a35050565b610e35848484610727565b5f8373ffffffffffffffffffffffffffffffffffffffff163b14610e7557610e5f8484848461165d565b610e7457610e7363d1a57ed660e01b611163565b5b5b50505050565b6060610e86826110c0565b610ec5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebc906127cd565b60405180910390fd5b5f610ece611787565b90505f815111610eec5760405180602001604052805f815250610f1a565b80610ef684611817565b600c604051602001610f0a939291906128a5565b6040516020818303038152906040525b915050919050565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b610fb861149d565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611028575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161101f9190611e85565b60405180910390fd5b6110318161157d565b50565b600b805461104190612405565b80601f016020809104026020016040519081016040528092919081815260200182805461106d90612405565b80156110b85780601f1061108f576101008083540402835291602001916110b8565b820191905f5260205f20905b81548152906001019060200180831161109b57829003601f168201915b505050505081565b5f816110ca611295565b1161115d576110d761129d565b8211156110ff576110f860045f8481526020019081526020015f20546118e1565b905061115e565b5f5482101561115c575f5b5f60045f8581526020019081526020015f205491508103611136578261112f906128d5565b925061110a565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b5b919050565b805f5260045ffd5b5f61117583610b3f565b90508180156111b757508073ffffffffffffffffffffffffffffffffffffffff1661119e6113f6565b73ffffffffffffffffffffffffffffffffffffffff1614155b156111e3576111cd816111c86113f6565b610f22565b6111e2576111e163cfb3b94260e01b611163565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b5f816112ce611295565b116113bd5760045f8381526020019081526020015f205490506112ef61129d565b821115611314576112ff816118e1565b6113ce5761131363df2d9b4260e01b611163565b5b5f8103611395575f5482106113345761133363df2d9b4260e01b611163565b5b5b60045f836001900393508381526020019081526020015f205490505f810315611390575f7c0100000000000000000000000000000000000000000000000000000000821603156113ce5761138f63df2d9b4260e01b611163565b5b611335565b5f7c0100000000000000000000000000000000000000000000000000000000821603156113ce575b6113cd63df2d9b4260e01b611163565b5b919050565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b5f8060e883901c905060e861145c868684611921565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6114a5611929565b73ffffffffffffffffffffffffffffffffffffffff166114c3610c56565b73ffffffffffffffffffffffffffffffffffffffff1614611522576114e6611929565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016115199190611e85565b60405180910390fd5b565b6002600a5403611569576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156090612946565b60405180910390fd5b6002600a81905550565b6001600a81905550565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611659828260405180602001604052805f815250611930565b5050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a026116826113f6565b8786866040518563ffffffff1660e01b81526004016116a494939291906129b6565b6020604051808303815f875af19250505080156116df57506040513d601f19601f820116820180604052508101906116dc9190612a14565b60015b611734573d805f811461170d576040519150601f19603f3d011682016040523d82523d5f602084013e611712565b606091505b505f81510361172c5761172b63d1a57ed660e01b611163565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600b805461179690612405565b80601f01602080910402602001604051908101604052809291908181526020018280546117c290612405565b801561180d5780601f106117e45761010080835404028352916020019161180d565b820191905f5260205f20905b8154815290600101906020018083116117f057829003601f168201915b5050505050905090565b60605f6001611825846119a6565b0190505f8167ffffffffffffffff81111561184357611842611f86565b5b6040519080825280601f01601f1916602001820160405280156118755781602001600182028036833780820191505090505b5090505f82602001820190505b6001156118d6578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816118cb576118ca612a3f565b5b0494505f8503611882575b819350505050919050565b5f7c0100000000000000000000000000000000000000000000000000000000821673ffffffffffffffffffffffffffffffffffffffff8316119050919050565b5f9392505050565b5f33905090565b61193a8383611af7565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146119a1575f805490505f83820390505b6119765f86838060010194508661165d565b61198b5761198a63d1a57ed660e01b611163565b5b81811061196457815f541461199e575f80fd5b50505b505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611a02577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816119f8576119f7612a3f565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611a3f576d04ee2d6d415b85acef81000000008381611a3557611a34612a3f565b5b0492506020810190505b662386f26fc100008310611a6e57662386f26fc100008381611a6457611a63612a3f565b5b0492506010810190505b6305f5e1008310611a97576305f5e1008381611a8d57611a8c612a3f565b5b0492506008810190505b6127108310611abc576127108381611ab257611ab1612a3f565b5b0492506004810190505b60648310611adf5760648381611ad557611ad4612a3f565b5b0492506002810190505b600a8310611aee576001810190505b80915050919050565b5f805490505f8203611b1457611b1363b562e8dd60e01b611163565b5b611b205f848385611440565b611b3e83611b2f5f865f611446565b611b3885611c6b565b1761146d565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f73ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161690505f8103611bef57611bee632e07630060e01b611163565b5b5f83830190505f839050611c0161129d565b600183031115611c1c57611c1b6381647e3a60e01b611163565b5b5b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4818160010191508103611c1d57815f81905550505050611c665f848385611497565b505050565b5f6001821460e11b9050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611cbf81611c8b565b8114611cc9575f80fd5b50565b5f81359050611cda81611cb6565b92915050565b5f60208284031215611cf557611cf4611c83565b5b5f611d0284828501611ccc565b91505092915050565b5f8115159050919050565b611d1f81611d0b565b82525050565b5f602082019050611d385f830184611d16565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015611d75578082015181840152602081019050611d5a565b5f8484015250505050565b5f601f19601f8301169050919050565b5f611d9a82611d3e565b611da48185611d48565b9350611db4818560208601611d58565b611dbd81611d80565b840191505092915050565b5f6020820190508181035f830152611de08184611d90565b905092915050565b5f819050919050565b611dfa81611de8565b8114611e04575f80fd5b50565b5f81359050611e1581611df1565b92915050565b5f60208284031215611e3057611e2f611c83565b5b5f611e3d84828501611e07565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611e6f82611e46565b9050919050565b611e7f81611e65565b82525050565b5f602082019050611e985f830184611e76565b92915050565b611ea781611e65565b8114611eb1575f80fd5b50565b5f81359050611ec281611e9e565b92915050565b5f8060408385031215611ede57611edd611c83565b5b5f611eeb85828601611eb4565b9250506020611efc85828601611e07565b9150509250929050565b611f0f81611de8565b82525050565b5f602082019050611f285f830184611f06565b92915050565b5f805f60608486031215611f4557611f44611c83565b5b5f611f5286828701611eb4565b9350506020611f6386828701611eb4565b9250506040611f7486828701611e07565b9150509250925092565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611fbc82611d80565b810181811067ffffffffffffffff82111715611fdb57611fda611f86565b5b80604052505050565b5f611fed611c7a565b9050611ff98282611fb3565b919050565b5f67ffffffffffffffff82111561201857612017611f86565b5b61202182611d80565b9050602081019050919050565b828183375f83830152505050565b5f61204e61204984611ffe565b611fe4565b90508281526020810184848401111561206a57612069611f82565b5b61207584828561202e565b509392505050565b5f82601f83011261209157612090611f7e565b5b81356120a184826020860161203c565b91505092915050565b5f602082840312156120bf576120be611c83565b5b5f82013567ffffffffffffffff8111156120dc576120db611c87565b5b6120e88482850161207d565b91505092915050565b5f6020828403121561210657612105611c83565b5b5f61211384828501611eb4565b91505092915050565b5f80fd5b5f80fd5b5f8083601f84011261213957612138611f7e565b5b8235905067ffffffffffffffff8111156121565761215561211c565b5b60208301915083602082028301111561217257612171612120565b5b9250929050565b5f805f604084860312156121905761218f611c83565b5b5f84013567ffffffffffffffff8111156121ad576121ac611c87565b5b6121b986828701612124565b935093505060206121cc86828701611e07565b9150509250925092565b5f80604083850312156121ec576121eb611c83565b5b5f6121f985828601611e07565b925050602061220a85828601611eb4565b9150509250929050565b61221d81611d0b565b8114612227575f80fd5b50565b5f8135905061223881612214565b92915050565b5f806040838503121561225457612253611c83565b5b5f61226185828601611eb4565b92505060206122728582860161222a565b9150509250929050565b5f67ffffffffffffffff82111561229657612295611f86565b5b61229f82611d80565b9050602081019050919050565b5f6122be6122b98461227c565b611fe4565b9050828152602081018484840111156122da576122d9611f82565b5b6122e584828561202e565b509392505050565b5f82601f83011261230157612300611f7e565b5b81356123118482602086016122ac565b91505092915050565b5f805f806080858703121561233257612331611c83565b5b5f61233f87828801611eb4565b945050602061235087828801611eb4565b935050604061236187828801611e07565b925050606085013567ffffffffffffffff81111561238257612381611c87565b5b61238e878288016122ed565b91505092959194509250565b5f80604083850312156123b0576123af611c83565b5b5f6123bd85828601611eb4565b92505060206123ce85828601611eb4565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061241c57607f821691505b60208210810361242f5761242e6123d8565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026124917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612456565b61249b8683612456565b95508019841693508086168417925050509392505050565b5f819050919050565b5f6124d66124d16124cc84611de8565b6124b3565b611de8565b9050919050565b5f819050919050565b6124ef836124bc565b6125036124fb826124dd565b848454612462565b825550505050565b5f90565b61251761250b565b6125228184846124e6565b505050565b5b818110156125455761253a5f8261250f565b600181019050612528565b5050565b601f82111561258a5761255b81612435565b61256484612447565b81016020851015612573578190505b61258761257f85612447565b830182612527565b50505b505050565b5f82821c905092915050565b5f6125aa5f198460080261258f565b1980831691505092915050565b5f6125c2838361259b565b9150826002028217905092915050565b6125db82611d3e565b67ffffffffffffffff8111156125f4576125f3611f86565b5b6125fe8254612405565b612609828285612549565b5f60209050601f83116001811461263a575f8415612628578287015190505b61263285826125b7565b865550612699565b601f19841661264886612435565b5f5b8281101561266f5784890151825560018201915060208501945060208101905061264a565b8683101561268c5784890151612688601f89168261259b565b8355505b6001600288020188555050505b505050505050565b5f81905092915050565b50565b5f6126b95f836126a1565b91506126c4826126ab565b5f82019050919050565b5f6126d8826126ae565b9150819050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61274682611de8565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036127785761277761270f565b5b600182019050919050565b7f446f6573206e6f742065786973740000000000000000000000000000000000005f82015250565b5f6127b7600e83611d48565b91506127c282612783565b602082019050919050565b5f6020820190508181035f8301526127e4816127ab565b9050919050565b5f81905092915050565b5f6127ff82611d3e565b61280981856127eb565b9350612819818560208601611d58565b80840191505092915050565b5f815461283181612405565b61283b81866127eb565b9450600182165f8114612855576001811461286a5761289c565b60ff198316865281151582028601935061289c565b61287385612435565b5f5b8381101561289457815481890152600182019150602081019050612875565b838801955050505b50505092915050565b5f6128b082866127f5565b91506128bc82856127f5565b91506128c88284612825565b9150819050949350505050565b5f6128df82611de8565b91505f82036128f1576128f061270f565b5b600182039050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f612930601f83611d48565b915061293b826128fc565b602082019050919050565b5f6020820190508181035f83015261295d81612924565b9050919050565b5f81519050919050565b5f82825260208201905092915050565b5f61298882612964565b612992818561296e565b93506129a2818560208601611d58565b6129ab81611d80565b840191505092915050565b5f6080820190506129c95f830187611e76565b6129d66020830186611e76565b6129e36040830185611f06565b81810360608301526129f5818461297e565b905095945050505050565b5f81519050612a0e81611cb6565b92915050565b5f60208284031215612a2957612a28611c83565b5b5f612a3684828501612a00565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffdfea264697066735822122060e5f718fe453b0fd3c049dd9976b2a51868ab0ccabe7322ef3f0519189cb26964736f6c63430008140033

Deployed Bytecode

0x60806040526004361061014a575f3560e01c806370a08231116100b5578063a22cb4651161006e578063a22cb46514610444578063b88d4fde1461046c578063c87b56dd14610488578063e985e9c5146104c4578063f2fde38b14610500578063fbca0ce1146105285761014a565b806370a082311461034e578063715018a61461038a578063751a144d146103a05780638da5cb5b146103c8578063951be370146103f257806395d89b411461041a5761014a565b806327fc0cff1161010757806327fc0cff146102525780632ce9af501461027a5780633ccfd60b146102a257806342842e0e146102cc57806352ee4696146102e85780636352211e146103125761014a565b806301ffc9a71461014e57806306fdde031461018a578063081812fc146101b4578063095ea7b3146101f057806318160ddd1461020c57806323b872dd14610236575b5f80fd5b348015610159575f80fd5b50610174600480360381019061016f9190611ce0565b610552565b6040516101819190611d25565b60405180910390f35b348015610195575f80fd5b5061019e6105e3565b6040516101ab9190611dc8565b60405180910390f35b3480156101bf575f80fd5b506101da60048036038101906101d59190611e1b565b610673565b6040516101e79190611e85565b60405180910390f35b61020a60048036038101906102059190611ec8565b6106cc565b005b348015610217575f80fd5b506102206106dc565b60405161022d9190611f15565b60405180910390f35b610250600480360381019061024b9190611f2e565b610727565b005b34801561025d575f80fd5b50610278600480360381019061027391906120aa565b6109d2565b005b348015610285575f80fd5b506102a0600480360381019061029b91906120aa565b6109ed565b005b3480156102ad575f80fd5b506102b6610a08565b6040516102c39190611d25565b60405180910390f35b6102e660048036038101906102e19190611f2e565b610a94565b005b3480156102f3575f80fd5b506102fc610ab3565b6040516103099190611dc8565b60405180910390f35b34801561031d575f80fd5b5061033860048036038101906103339190611e1b565b610b3f565b6040516103459190611e85565b60405180910390f35b348015610359575f80fd5b50610374600480360381019061036f91906120f1565b610b50565b6040516103819190611f15565b60405180910390f35b348015610395575f80fd5b5061039e610be4565b005b3480156103ab575f80fd5b506103c660048036038101906103c19190612179565b610bf7565b005b3480156103d3575f80fd5b506103dc610c56565b6040516103e99190611e85565b60405180910390f35b3480156103fd575f80fd5b50610418600480360381019061041391906121d6565b610c7e565b005b348015610425575f80fd5b5061042e610c94565b60405161043b9190611dc8565b60405180910390f35b34801561044f575f80fd5b5061046a6004803603810190610465919061223e565b610d24565b005b6104866004803603810190610481919061231a565b610e2a565b005b348015610493575f80fd5b506104ae60048036038101906104a99190611e1b565b610e7b565b6040516104bb9190611dc8565b60405180910390f35b3480156104cf575f80fd5b506104ea60048036038101906104e5919061239a565b610f22565b6040516104f79190611d25565b60405180910390f35b34801561050b575f80fd5b50610526600480360381019061052191906120f1565b610fb0565b005b348015610533575f80fd5b5061053c611034565b6040516105499190611dc8565b60405180910390f35b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806105ac57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806105dc5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546105f290612405565b80601f016020809104026020016040519081016040528092919081815260200182805461061e90612405565b80156106695780601f1061064057610100808354040283529160200191610669565b820191905f5260205f20905b81548152906001019060200180831161064c57829003601f168201915b5050505050905090565b5f61067d826110c0565b6106925761069163cf4700e460e01b611163565b5b60065f8381526020019081526020015f205f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6106d88282600161116b565b5050565b5f6106e5611295565b6001545f54030390507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61071761129d565b1461072457600854810190505b90565b5f610731826112c4565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146107a6576107a563a114810060e01b611163565b5b5f806107b1846113d3565b915091506107c781876107c26113f6565b6113fd565b6107f2576107dc866107d76113f6565b610f22565b6107f1576107f06359c896be60e01b611163565b5b5b6107ff8686866001611440565b8015610809575f82555b60055f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600190039190508190555060055f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8154600101919050819055506108d1856108ad888887611446565b7c02000000000000000000000000000000000000000000000000000000001761146d565b60045f8681526020019081526020015f20819055505f7c020000000000000000000000000000000000000000000000000000000084160361094d575f6001850190505f60045f8381526020019081526020015f20540361094b575f54811461094a578360045f8381526020019081526020015f20819055505b5b505b5f73ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a45f81036109bc576109bb63ea553b3460e01b611163565b5b6109c98787876001611497565b50505050505050565b6109da61149d565b80600b90816109e991906125d2565b5050565b6109f561149d565b80600c9081610a0491906125d2565b5050565b5f610a1161149d565b610a19611524565b610a21610c56565b73ffffffffffffffffffffffffffffffffffffffff1647604051610a44906126ce565b5f6040518083038185875af1925050503d805f8114610a7e576040519150601f19603f3d011682016040523d82523d5f602084013e610a83565b606091505b505080915050610a91611573565b90565b610aae83838360405180602001604052805f815250610e2a565b505050565b600c8054610ac090612405565b80601f0160208091040260200160405190810160405280929190818152602001828054610aec90612405565b8015610b375780601f10610b0e57610100808354040283529160200191610b37565b820191905f5260205f20905b815481529060010190602001808311610b1a57829003601f168201915b505050505081565b5f610b49826112c4565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610b9557610b94638f4eb60460e01b611163565b5b67ffffffffffffffff60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054169050919050565b610bec61149d565b610bf55f61157d565b565b610bff61149d565b5f5b83839050811015610c5057610c3d848483818110610c2257610c216126e2565b5b9050602002016020810190610c3791906120f1565b83611640565b8080610c489061273c565b915050610c01565b50505050565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610c8661149d565b610c908183611640565b5050565b606060038054610ca390612405565b80601f0160208091040260200160405190810160405280929190818152602001828054610ccf90612405565b8015610d1a5780601f10610cf157610100808354040283529160200191610d1a565b820191905f5260205f20905b815481529060010190602001808311610cfd57829003601f168201915b5050505050905090565b8060075f610d306113f6565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16610dd96113f6565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610e1e9190611d25565b60405180910390a35050565b610e35848484610727565b5f8373ffffffffffffffffffffffffffffffffffffffff163b14610e7557610e5f8484848461165d565b610e7457610e7363d1a57ed660e01b611163565b5b5b50505050565b6060610e86826110c0565b610ec5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebc906127cd565b60405180910390fd5b5f610ece611787565b90505f815111610eec5760405180602001604052805f815250610f1a565b80610ef684611817565b600c604051602001610f0a939291906128a5565b6040516020818303038152906040525b915050919050565b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b610fb861149d565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611028575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161101f9190611e85565b60405180910390fd5b6110318161157d565b50565b600b805461104190612405565b80601f016020809104026020016040519081016040528092919081815260200182805461106d90612405565b80156110b85780601f1061108f576101008083540402835291602001916110b8565b820191905f5260205f20905b81548152906001019060200180831161109b57829003601f168201915b505050505081565b5f816110ca611295565b1161115d576110d761129d565b8211156110ff576110f860045f8481526020019081526020015f20546118e1565b905061115e565b5f5482101561115c575f5b5f60045f8581526020019081526020015f205491508103611136578261112f906128d5565b925061110a565b5f7c01000000000000000000000000000000000000000000000000000000008216149150505b5b5b919050565b805f5260045ffd5b5f61117583610b3f565b90508180156111b757508073ffffffffffffffffffffffffffffffffffffffff1661119e6113f6565b73ffffffffffffffffffffffffffffffffffffffff1614155b156111e3576111cd816111c86113f6565b610f22565b6111e2576111e163cfb3b94260e01b611163565b5b5b8360065f8581526020019081526020015f205f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b5f6001905090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b5f816112ce611295565b116113bd5760045f8381526020019081526020015f205490506112ef61129d565b821115611314576112ff816118e1565b6113ce5761131363df2d9b4260e01b611163565b5b5f8103611395575f5482106113345761133363df2d9b4260e01b611163565b5b5b60045f836001900393508381526020019081526020015f205490505f810315611390575f7c0100000000000000000000000000000000000000000000000000000000821603156113ce5761138f63df2d9b4260e01b611163565b5b611335565b5f7c0100000000000000000000000000000000000000000000000000000000821603156113ce575b6113cd63df2d9b4260e01b611163565b5b919050565b5f805f60065f8581526020019081526020015f2090508092508254915050915091565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b5f8060e883901c905060e861145c868684611921565b62ffffff16901b9150509392505050565b5f73ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6114a5611929565b73ffffffffffffffffffffffffffffffffffffffff166114c3610c56565b73ffffffffffffffffffffffffffffffffffffffff1614611522576114e6611929565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016115199190611e85565b60405180910390fd5b565b6002600a5403611569576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156090612946565b60405180910390fd5b6002600a81905550565b6001600a81905550565b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611659828260405180602001604052805f815250611930565b5050565b5f8373ffffffffffffffffffffffffffffffffffffffff1663150b7a026116826113f6565b8786866040518563ffffffff1660e01b81526004016116a494939291906129b6565b6020604051808303815f875af19250505080156116df57506040513d601f19601f820116820180604052508101906116dc9190612a14565b60015b611734573d805f811461170d576040519150601f19603f3d011682016040523d82523d5f602084013e611712565b606091505b505f81510361172c5761172b63d1a57ed660e01b611163565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600b805461179690612405565b80601f01602080910402602001604051908101604052809291908181526020018280546117c290612405565b801561180d5780601f106117e45761010080835404028352916020019161180d565b820191905f5260205f20905b8154815290600101906020018083116117f057829003601f168201915b5050505050905090565b60605f6001611825846119a6565b0190505f8167ffffffffffffffff81111561184357611842611f86565b5b6040519080825280601f01601f1916602001820160405280156118755781602001600182028036833780820191505090505b5090505f82602001820190505b6001156118d6578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816118cb576118ca612a3f565b5b0494505f8503611882575b819350505050919050565b5f7c0100000000000000000000000000000000000000000000000000000000821673ffffffffffffffffffffffffffffffffffffffff8316119050919050565b5f9392505050565b5f33905090565b61193a8383611af7565b5f8373ffffffffffffffffffffffffffffffffffffffff163b146119a1575f805490505f83820390505b6119765f86838060010194508661165d565b61198b5761198a63d1a57ed660e01b611163565b5b81811061196457815f541461199e575f80fd5b50505b505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611a02577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816119f8576119f7612a3f565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611a3f576d04ee2d6d415b85acef81000000008381611a3557611a34612a3f565b5b0492506020810190505b662386f26fc100008310611a6e57662386f26fc100008381611a6457611a63612a3f565b5b0492506010810190505b6305f5e1008310611a97576305f5e1008381611a8d57611a8c612a3f565b5b0492506008810190505b6127108310611abc576127108381611ab257611ab1612a3f565b5b0492506004810190505b60648310611adf5760648381611ad557611ad4612a3f565b5b0492506002810190505b600a8310611aee576001810190505b80915050919050565b5f805490505f8203611b1457611b1363b562e8dd60e01b611163565b5b611b205f848385611440565b611b3e83611b2f5f865f611446565b611b3885611c6b565b1761146d565b60045f8381526020019081526020015f2081905550600160406001901b17820260055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505f73ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161690505f8103611bef57611bee632e07630060e01b611163565b5b5f83830190505f839050611c0161129d565b600183031115611c1c57611c1b6381647e3a60e01b611163565b5b5b80835f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4818160010191508103611c1d57815f81905550505050611c665f848385611497565b505050565b5f6001821460e11b9050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611cbf81611c8b565b8114611cc9575f80fd5b50565b5f81359050611cda81611cb6565b92915050565b5f60208284031215611cf557611cf4611c83565b5b5f611d0284828501611ccc565b91505092915050565b5f8115159050919050565b611d1f81611d0b565b82525050565b5f602082019050611d385f830184611d16565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015611d75578082015181840152602081019050611d5a565b5f8484015250505050565b5f601f19601f8301169050919050565b5f611d9a82611d3e565b611da48185611d48565b9350611db4818560208601611d58565b611dbd81611d80565b840191505092915050565b5f6020820190508181035f830152611de08184611d90565b905092915050565b5f819050919050565b611dfa81611de8565b8114611e04575f80fd5b50565b5f81359050611e1581611df1565b92915050565b5f60208284031215611e3057611e2f611c83565b5b5f611e3d84828501611e07565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611e6f82611e46565b9050919050565b611e7f81611e65565b82525050565b5f602082019050611e985f830184611e76565b92915050565b611ea781611e65565b8114611eb1575f80fd5b50565b5f81359050611ec281611e9e565b92915050565b5f8060408385031215611ede57611edd611c83565b5b5f611eeb85828601611eb4565b9250506020611efc85828601611e07565b9150509250929050565b611f0f81611de8565b82525050565b5f602082019050611f285f830184611f06565b92915050565b5f805f60608486031215611f4557611f44611c83565b5b5f611f5286828701611eb4565b9350506020611f6386828701611eb4565b9250506040611f7486828701611e07565b9150509250925092565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611fbc82611d80565b810181811067ffffffffffffffff82111715611fdb57611fda611f86565b5b80604052505050565b5f611fed611c7a565b9050611ff98282611fb3565b919050565b5f67ffffffffffffffff82111561201857612017611f86565b5b61202182611d80565b9050602081019050919050565b828183375f83830152505050565b5f61204e61204984611ffe565b611fe4565b90508281526020810184848401111561206a57612069611f82565b5b61207584828561202e565b509392505050565b5f82601f83011261209157612090611f7e565b5b81356120a184826020860161203c565b91505092915050565b5f602082840312156120bf576120be611c83565b5b5f82013567ffffffffffffffff8111156120dc576120db611c87565b5b6120e88482850161207d565b91505092915050565b5f6020828403121561210657612105611c83565b5b5f61211384828501611eb4565b91505092915050565b5f80fd5b5f80fd5b5f8083601f84011261213957612138611f7e565b5b8235905067ffffffffffffffff8111156121565761215561211c565b5b60208301915083602082028301111561217257612171612120565b5b9250929050565b5f805f604084860312156121905761218f611c83565b5b5f84013567ffffffffffffffff8111156121ad576121ac611c87565b5b6121b986828701612124565b935093505060206121cc86828701611e07565b9150509250925092565b5f80604083850312156121ec576121eb611c83565b5b5f6121f985828601611e07565b925050602061220a85828601611eb4565b9150509250929050565b61221d81611d0b565b8114612227575f80fd5b50565b5f8135905061223881612214565b92915050565b5f806040838503121561225457612253611c83565b5b5f61226185828601611eb4565b92505060206122728582860161222a565b9150509250929050565b5f67ffffffffffffffff82111561229657612295611f86565b5b61229f82611d80565b9050602081019050919050565b5f6122be6122b98461227c565b611fe4565b9050828152602081018484840111156122da576122d9611f82565b5b6122e584828561202e565b509392505050565b5f82601f83011261230157612300611f7e565b5b81356123118482602086016122ac565b91505092915050565b5f805f806080858703121561233257612331611c83565b5b5f61233f87828801611eb4565b945050602061235087828801611eb4565b935050604061236187828801611e07565b925050606085013567ffffffffffffffff81111561238257612381611c87565b5b61238e878288016122ed565b91505092959194509250565b5f80604083850312156123b0576123af611c83565b5b5f6123bd85828601611eb4565b92505060206123ce85828601611eb4565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061241c57607f821691505b60208210810361242f5761242e6123d8565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026124917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612456565b61249b8683612456565b95508019841693508086168417925050509392505050565b5f819050919050565b5f6124d66124d16124cc84611de8565b6124b3565b611de8565b9050919050565b5f819050919050565b6124ef836124bc565b6125036124fb826124dd565b848454612462565b825550505050565b5f90565b61251761250b565b6125228184846124e6565b505050565b5b818110156125455761253a5f8261250f565b600181019050612528565b5050565b601f82111561258a5761255b81612435565b61256484612447565b81016020851015612573578190505b61258761257f85612447565b830182612527565b50505b505050565b5f82821c905092915050565b5f6125aa5f198460080261258f565b1980831691505092915050565b5f6125c2838361259b565b9150826002028217905092915050565b6125db82611d3e565b67ffffffffffffffff8111156125f4576125f3611f86565b5b6125fe8254612405565b612609828285612549565b5f60209050601f83116001811461263a575f8415612628578287015190505b61263285826125b7565b865550612699565b601f19841661264886612435565b5f5b8281101561266f5784890151825560018201915060208501945060208101905061264a565b8683101561268c5784890151612688601f89168261259b565b8355505b6001600288020188555050505b505050505050565b5f81905092915050565b50565b5f6126b95f836126a1565b91506126c4826126ab565b5f82019050919050565b5f6126d8826126ae565b9150819050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61274682611de8565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036127785761277761270f565b5b600182019050919050565b7f446f6573206e6f742065786973740000000000000000000000000000000000005f82015250565b5f6127b7600e83611d48565b91506127c282612783565b602082019050919050565b5f6020820190508181035f8301526127e4816127ab565b9050919050565b5f81905092915050565b5f6127ff82611d3e565b61280981856127eb565b9350612819818560208601611d58565b80840191505092915050565b5f815461283181612405565b61283b81866127eb565b9450600182165f8114612855576001811461286a5761289c565b60ff198316865281151582028601935061289c565b61287385612435565b5f5b8381101561289457815481890152600182019150602081019050612875565b838801955050505b50505092915050565b5f6128b082866127f5565b91506128bc82856127f5565b91506128c88284612825565b9150819050949350505050565b5f6128df82611de8565b91505f82036128f1576128f061270f565b5b600182039050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f612930601f83611d48565b915061293b826128fc565b602082019050919050565b5f6020820190508181035f83015261295d81612924565b9050919050565b5f81519050919050565b5f82825260208201905092915050565b5f61298882612964565b612992818561296e565b93506129a2818560208601611d58565b6129ab81611d80565b840191505092915050565b5f6080820190506129c95f830187611e76565b6129d66020830186611e76565b6129e36040830185611f06565b81810360608301526129f5818461297e565b905095945050505050565b5f81519050612a0e81611cb6565b92915050565b5f60208284031215612a2957612a28611c83565b5b5f612a3684828501612a00565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffdfea264697066735822122060e5f718fe453b0fd3c049dd9976b2a51868ab0ccabe7322ef3f0519189cb26964736f6c63430008140033

Deployed Bytecode Sourcemap

93163:1619:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21790:657;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22728:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30322:235;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30017:128;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;17700:591;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34818:3675;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94362:96;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94468:116;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94598:175;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38599:205;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93383:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24212:156;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19512:248;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71018:107;;;;;;;;;;;;;:::i;:::-;;93568:193;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70303:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93430:128;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;22918:108;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30923:240;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;39436:438;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93999:353;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31334:168;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71292:230;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93339:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21790:657;21875:4;22226:10;22211:25;;:11;:25;;;;:104;;;;22305:10;22290:25;;:11;:25;;;;22211:104;:183;;;;22384:10;22369:25;;:11;:25;;;;22211:183;22189:205;;21790:657;;;:::o;22728:104::-;22782:13;22817:5;22810:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22728:104;:::o;30322:235::-;30398:7;30425:16;30433:7;30425;:16::i;:::-;30420:73;;30443:50;30451:41;;;30443:7;:50::i;:::-;30420:73;30517:15;:24;30533:7;30517:24;;;;;;;;;;;:30;;;;;;;;;;;;30510:37;;30322:235;;;:::o;30017:128::-;30108:27;30117:2;30121:7;30130:4;30108:8;:27::i;:::-;30017:128;;:::o;17700:591::-;17761:14;18171:15;:13;:15::i;:::-;18156:12;;18140:13;;:28;:46;18131:55;;18228:17;18207;:15;:17::i;:::-;:38;18203:65;;18257:11;;18247:21;;;;18203:65;17700:591;:::o;34818:3675::-;34970:27;35000;35019:7;35000:18;:27::i;:::-;34970:57;;13420:14;35177:4;35161:22;;:41;35138:66;;35266:4;35225:45;;35241:19;35225:45;;;35221:95;;35272:44;35280:35;;;35272:7;:44::i;:::-;35221:95;35334:27;35363:23;35390:35;35417:7;35390:26;:35::i;:::-;35333:92;;;;35531:68;35556:15;35573:4;35579:19;:17;:19::i;:::-;35531:24;:68::i;:::-;35526:191;;35621:43;35638:4;35644:19;:17;:19::i;:::-;35621:16;:43::i;:::-;35616:101;;35666:51;35674:42;;;35666:7;:51::i;:::-;35616:101;35526:191;35734:43;35756:4;35762:2;35766:7;35775:1;35734:21;:43::i;:::-;35878:15;35875:166;;;36022:1;36001:19;35994:30;35875:166;36437:18;:24;36456:4;36437:24;;;;;;;;;;;;;;;;36435:26;;;;;;;;;;;;36508:18;:22;36527:2;36508:22;;;;;;;;;;;;;;;;36506:24;;;;;;;;;;;36844:152;36883:2;36934:45;36949:4;36955:2;36959:19;36934:14;:45::i;:::-;13000:8;36906:73;36844:18;:152::i;:::-;36815:17;:26;36833:7;36815:26;;;;;;;;;;;:181;;;;37173:1;13000:8;37122:19;:47;:52;37118:647;;37197:19;37229:1;37219:7;:11;37197:33;;37390:1;37356:17;:30;37374:11;37356:30;;;;;;;;;;;;:35;37352:396;;37498:13;;37483:11;:28;37479:248;;37682:19;37649:17;:30;37667:11;37649:30;;;;;;;;;;;:52;;;;37479:248;37352:396;37176:589;37118:647;37886:16;13420:14;37921:2;37905:20;;:39;37886:58;;38303:7;38265:8;38229:4;38169:25;38112:1;38053;38028:313;38382:1;38370:8;:13;38366:58;;38385:39;38393:30;;;38385:7;:39::i;:::-;38366:58;38441:42;38462:4;38468:2;38472:7;38481:1;38441:20;:42::i;:::-;34957:3536;;;;34818:3675;;;:::o;94362:96::-;70175:13;:11;:13::i;:::-;94442:8:::1;94432:7;:18;;;;;;:::i;:::-;;94362:96:::0;:::o;94468:116::-;70175:13;:11;:13::i;:::-;94563::::1;94548:12;:28;;;;;;:::i;:::-;;94468:116:::0;:::o;94598:175::-;94656:7;70175:13;:11;:13::i;:::-;66492:21:::1;:19;:21::i;:::-;94693:7:::2;:5;:7::i;:::-;94685:21;;94714;94685:55;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94677:63;;;;;66540:20:::1;:18;:20::i;:::-;94598:175:::0;:::o;38599:205::-;38755:39;38772:4;38778:2;38782:7;38755:39;;;;;;;;;;;;:16;:39::i;:::-;38599:205;;;:::o;93383:36::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;24212:156::-;24284:7;24329:27;24348:7;24329:18;:27::i;:::-;24306:52;;24212:156;;;:::o;19512:248::-;19584:7;19627:1;19610:19;;:5;:19;;;19606:69;;19631:44;19639:35;;;19631:7;:44::i;:::-;19606:69;11896:13;19695:18;:25;19714:5;19695:25;;;;;;;;;;;;;;;;:55;19688:62;;19512:248;;;:::o;71018:107::-;70175:13;:11;:13::i;:::-;71085:30:::1;71112:1;71085:18;:30::i;:::-;71018:107::o:0;93568:193::-;70175:13;:11;:13::i;:::-;93670:6:::1;93665:89;93686:2;;:9;;93682:1;:13;93665:89;;;93715:29;93725:2;;93728:1;93725:5;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;93732:11;93715:9;:29::i;:::-;93697:3;;;;;:::i;:::-;;;;93665:89;;;;93568:193:::0;;;:::o;70303:91::-;70349:7;70378:6;;;;;;;;;;;70371:13;;70303:91;:::o;93430:128::-;70175:13;:11;:13::i;:::-;93517:33:::1;93527:9;93538:11;93517:9;:33::i;:::-;93430:128:::0;;:::o;22918:108::-;22974:13;23009:7;23002:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22918:108;:::o;30923:240::-;31072:8;31020:18;:39;31039:19;:17;:19::i;:::-;31020:39;;;;;;;;;;;;;;;:49;31060:8;31020:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;31134:8;31098:55;;31113:19;:17;:19::i;:::-;31098:55;;;31144:8;31098:55;;;;;;:::i;:::-;;;;;;;;30923:240;;:::o;39436:438::-;39623:31;39636:4;39642:2;39646:7;39623:12;:31::i;:::-;39689:1;39671:2;:14;;;:19;39667:198;;39712:56;39743:4;39749:2;39753:7;39762:5;39712:30;:56::i;:::-;39707:158;;39791:56;39799:47;;;39791:7;:56::i;:::-;39707:158;39667:198;39436:438;;;;:::o;93999:353::-;94073:13;94105:17;94113:8;94105:7;:17::i;:::-;94097:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;94150:28;94181:10;:8;:10::i;:::-;94150:41;;94238:1;94213:14;94207:28;:32;:137;;;;;;;;;;;;;;;;;94277:14;94293:19;:8;:17;:19::i;:::-;94314:12;94260:67;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;94207:137;94200:144;;;93999:353;;;:::o;31334:168::-;31431:4;31457:18;:25;31476:5;31457:25;;;;;;;;;;;;;;;:35;31483:8;31457:35;;;;;;;;;;;;;;;;;;;;;;;;;31450:42;;31334:168;;;;:::o;71292:230::-;70175:13;:11;:13::i;:::-;71399:1:::1;71379:22;;:8;:22;;::::0;71375:97:::1;;71455:1;71427:31;;;;;;;;;;;:::i;:::-;;;;;;;;71375:97;71484:28;71503:8;71484:18;:28::i;:::-;71292:230:::0;:::o;93339:37::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;31778:495::-;31843:11;31892:7;31873:15;:13;:15::i;:::-;:26;31869:395;;31932:17;:15;:17::i;:::-;31922:7;:27;31918:90;;;31958:50;31981:17;:26;31999:7;31981:26;;;;;;;;;;;;31958:22;:50::i;:::-;31951:57;;;;31918:90;32043:13;;32033:7;:23;32029:222;;;32079:14;32114:60;32162:1;32131:17;:26;32149:7;32131:26;;;;;;;;;;;;32122:35;;;32121:42;32114:60;;32165:9;;;;:::i;:::-;;;32114:60;;;32232:1;12708:8;32204:6;:24;:29;32195:38;;32058:193;32029:222;31869:395;31778:495;;;;:::o;63855:175::-;63960:13;63954:4;63947:27;64003:4;63997;63990:18;54840:502;54979:13;54995:16;55003:7;54995;:16::i;:::-;54979:32;;55032:13;:45;;;;;55072:5;55049:28;;:19;:17;:19::i;:::-;:28;;;;55032:45;55028:207;;;55099:44;55116:5;55123:19;:17;:19::i;:::-;55099:16;:44::i;:::-;55094:141;;55166:51;55174:42;;;55166:7;:51::i;:::-;55094:141;55028:207;55284:2;55251:15;:24;55267:7;55251:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;55324:7;55320:2;55304:28;;55313:5;55304:28;;;;;;;;;;;;54966:376;54840:502;;;:::o;93890:99::-;93955:7;93980:1;93973:8;;93890:99;:::o;17166:114::-;17224:7;17253:17;17246:24;;17166:114;:::o;25775:2293::-;25842:14;25894:7;25875:15;:13;:15::i;:::-;:26;25871:2128;;25929:17;:26;25947:7;25929:26;;;;;;;;;;;;25920:35;;25990:17;:15;:17::i;:::-;25980:7;:27;25976:189;;;26034:30;26057:6;26034:22;:30::i;:::-;26066:13;26030:49;26100:47;26108:38;;;26100:7;:47::i;:::-;25976:189;26282:1;26272:6;:11;26268:1336;;26321:13;;26310:7;:24;26306:77;;26336:47;26344:38;;;26336:7;:47::i;:::-;26306:77;26960:627;27042:17;:28;27060:9;;;;;;;27042:28;;;;;;;;;;;;27033:37;;27134:1;27124:6;:11;27120:25;27137:8;27120:25;27202:1;12708:8;27174:6;:24;:29;27170:48;27205:13;27170:48;27518:47;27526:38;;;27518:7;:47::i;:::-;26960:627;;;26268:1336;27969:1;12708:8;27941:6;:24;:29;27937:48;27972:13;27937:48;25871:2128;28011:47;28019:38;;;28011:7;:47::i;:::-;25775:2293;;;;:::o;33653:507::-;33761:27;33790:23;33835:38;33876:15;:24;33892:7;33876:24;;;;;;;;;;;33835:65;;34059:18;34036:41;;34118:19;34112:26;34093:45;;34019:132;33653:507;;;:::o;61738:109::-;61798:7;61827:10;61820:17;;61738:109;:::o;32845:685::-;33002:11;33173:16;33166:5;33162:28;33153:37;;33337:16;33326:9;33322:32;33309:45;;33491:15;33480:9;33477:30;33469:5;33458:9;33455:20;33452:56;33442:66;;32845:685;;;;;:::o;40572:169::-;;;;;:::o;61011:325::-;61154:7;61176:16;13130:3;61202:19;:41;;61176:68;;13130:3;61272:31;61283:4;61289:2;61293:9;61272:10;:31::i;:::-;61264:40;;:62;;61257:69;;;61011:325;;;;;:::o;28646:464::-;28726:14;28900:16;28893:5;28889:28;28880:37;;29081:5;29067:11;29042:23;29038:41;29035:52;29028:5;29025:63;29015:73;;28646:464;;;;:::o;41442:168::-;;;;;:::o;70482:174::-;70555:12;:10;:12::i;:::-;70544:23;;:7;:5;:7::i;:::-;:23;;;70540:107;;70620:12;:10;:12::i;:::-;70593:40;;;;;;;;;;;:::i;:::-;;;;;;;;70540:107;70482:174::o;66582:305::-;65942:1;66720:7;;:19;66712:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;65942:1;66859:7;:18;;;;66582:305::o;66899:221::-;65896:1;67088:7;:22;;;;66899:221::o;71694:199::-;71770:16;71789:6;;;;;;;;;;;71770:25;;71817:8;71808:6;;:17;;;;;;;;;;;;;;;;;;71874:8;71843:40;;71864:8;71843:40;;;;;;;;;;;;71757:136;71694:199;:::o;49766:116::-;49845:27;49855:2;49859:8;49845:27;;;;;;;;;;;;:9;:27::i;:::-;49766:116;;:::o;42074:727::-;42247:4;42295:2;42270:45;;;42316:19;:17;:19::i;:::-;42337:4;42343:7;42352:5;42270:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;42266:526;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42580:1;42563:6;:13;:18;42559:119;;42604:56;42612:47;;;42604:7;:56::i;:::-;42559:119;42754:6;42748:13;42739:6;42735:2;42731:15;42724:38;42266:526;42445:54;;;42435:64;;;:6;:64;;;;42428:71;;;42074:727;;;;;;:::o;93773:106::-;93833:13;93864:7;93857:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93773:106;:::o;90377:758::-;90433:13;90488:14;90525:1;90505:17;90516:5;90505:10;:17::i;:::-;:21;90488:38;;90543:20;90577:6;90566:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90543:41;;90601:11;90736:6;90732:2;90728:15;90720:6;90716:28;90709:35;;90777:306;90784:4;90777:306;;;90811:5;;;;;;;;90959:10;90954:2;90947:5;90943:14;90938:32;90933:3;90925:46;91021:2;91012:11;;;;;;:::i;:::-;;;;;91057:1;91048:5;:10;90777:306;91044:21;90777:306;91106:6;91099:13;;;;;90377:758;;;:::o;32379:347::-;32449:11;32687:15;32679:6;32675:28;32656:16;32648:6;32644:29;32641:63;32631:73;;32379:347;;;:::o;60692:155::-;60837:6;60692:155;;;;;:::o;68174:102::-;68227:7;68256:10;68249:17;;68174:102;:::o;48843:829::-;48984:19;48990:2;48994:8;48984:5;:19::i;:::-;49069:1;49051:2;:14;;;:19;49047:603;;49093:11;49107:13;;49093:27;;49141:13;49163:8;49157:3;:14;49141:30;;49192:250;49225:62;49264:1;49268:2;49272:7;;;;;;49281:5;49225:30;:62::i;:::-;49220:180;;49318:56;49326:47;;;49318:7;:56::i;:::-;49220:180;49437:3;49429:5;:11;49192:250;;49619:3;49602:13;;:20;49598:34;;49624:8;;;49598:34;49072:578;;49047:603;48843:829;;;:::o;85109:1012::-;85162:7;85184:14;85201:1;85184:18;;85255:8;85246:5;:17;85242:112;;85295:8;85286:17;;;;;;:::i;:::-;;;;;85334:2;85324:12;;;;85242:112;85383:8;85374:5;:17;85370:112;;85423:8;85414:17;;;;;;:::i;:::-;;;;;85462:2;85452:12;;;;85370:112;85511:8;85502:5;:17;85498:112;;85551:8;85542:17;;;;;;:::i;:::-;;;;;85590:2;85580:12;;;;85498:112;85639:7;85630:5;:16;85626:109;;85678:7;85669:16;;;;;;:::i;:::-;;;;;85716:1;85706:11;;;;85626:109;85764:7;85755:5;:16;85751:109;;85803:7;85794:16;;;;;;:::i;:::-;;;;;85841:1;85831:11;;;;85751:109;85889:7;85880:5;:16;85876:109;;85928:7;85919:16;;;;;;:::i;:::-;;;;;85966:1;85956:11;;;;85876:109;86014:7;86005:5;:16;86001:72;;86054:1;86044:11;;;;86001:72;86105:6;86098:13;;;85109:1012;;;:::o;43295:2511::-;43370:20;43393:13;;43370:36;;43435:1;43423:8;:13;43419:53;;43438:34;43446:25;;;43438:7;:34::i;:::-;43419:53;43489:61;43519:1;43523:2;43527:12;43541:8;43489:21;:61::i;:::-;44045:145;44084:2;44140:33;44163:1;44167:2;44171:1;44140:14;:33::i;:::-;44107:30;44128:8;44107:20;:30::i;:::-;:66;44045:18;:145::i;:::-;44011:17;:31;44029:12;44011:31;;;;;;;;;;;:179;;;;44491:1;12040:2;44461:1;:26;;44460:32;44448:8;:45;44422:18;:22;44441:2;44422:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;44610:16;13420:14;44645:2;44629:20;;:39;44610:58;;44705:1;44693:8;:13;44689:54;;44708:35;44716:26;;;44708:7;:35::i;:::-;44689:54;44764:11;44793:8;44778:12;:23;44764:37;;44818:15;44836:12;44818:30;;44883:17;:15;:17::i;:::-;44879:1;44873:3;:7;:27;44869:77;;;44902:44;44910:35;;;44902:7;:44::i;:::-;44869:77;44967:704;45404:7;45358:8;45311:1;45243:25;45178:1;45111;45078:372;45666:3;45653:9;;;;;;:16;44967:704;;45707:3;45691:13;:19;;;;43748:1976;;;45736:60;45765:1;45769:2;45773:12;45787:8;45736:20;:60::i;:::-;43357:2449;43295:2511;;:::o;29222:336::-;29292:14;29533:1;29523:8;29520:15;29494:24;29490:46;29480:56;;29222:336;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:118::-;4977:24;4995:5;4977:24;:::i;:::-;4972:3;4965:37;4890:118;;:::o;5014:222::-;5107:4;5145:2;5134:9;5130:18;5122:26;;5158:71;5226:1;5215:9;5211:17;5202:6;5158:71;:::i;:::-;5014:222;;;;:::o;5242:619::-;5319:6;5327;5335;5384:2;5372:9;5363:7;5359:23;5355:32;5352:119;;;5390:79;;:::i;:::-;5352:119;5510:1;5535:53;5580:7;5571:6;5560:9;5556:22;5535:53;:::i;:::-;5525:63;;5481:117;5637:2;5663:53;5708:7;5699:6;5688:9;5684:22;5663:53;:::i;:::-;5653:63;;5608:118;5765:2;5791:53;5836:7;5827:6;5816:9;5812:22;5791:53;:::i;:::-;5781:63;;5736:118;5242:619;;;;;:::o;5867:117::-;5976:1;5973;5966:12;5990:117;6099:1;6096;6089:12;6113:180;6161:77;6158:1;6151:88;6258:4;6255:1;6248:15;6282:4;6279:1;6272:15;6299:281;6382:27;6404:4;6382:27;:::i;:::-;6374:6;6370:40;6512:6;6500:10;6497:22;6476:18;6464:10;6461:34;6458:62;6455:88;;;6523:18;;:::i;:::-;6455:88;6563:10;6559:2;6552:22;6342:238;6299:281;;:::o;6586:129::-;6620:6;6647:20;;:::i;:::-;6637:30;;6676:33;6704:4;6696:6;6676:33;:::i;:::-;6586:129;;;:::o;6721:308::-;6783:4;6873:18;6865:6;6862:30;6859:56;;;6895:18;;:::i;:::-;6859:56;6933:29;6955:6;6933:29;:::i;:::-;6925:37;;7017:4;7011;7007:15;6999:23;;6721:308;;;:::o;7035:146::-;7132:6;7127:3;7122;7109:30;7173:1;7164:6;7159:3;7155:16;7148:27;7035:146;;;:::o;7187:425::-;7265:5;7290:66;7306:49;7348:6;7306:49;:::i;:::-;7290:66;:::i;:::-;7281:75;;7379:6;7372:5;7365:21;7417:4;7410:5;7406:16;7455:3;7446:6;7441:3;7437:16;7434:25;7431:112;;;7462:79;;:::i;:::-;7431:112;7552:54;7599:6;7594:3;7589;7552:54;:::i;:::-;7271:341;7187:425;;;;;:::o;7632:340::-;7688:5;7737:3;7730:4;7722:6;7718:17;7714:27;7704:122;;7745:79;;:::i;:::-;7704:122;7862:6;7849:20;7887:79;7962:3;7954:6;7947:4;7939:6;7935:17;7887:79;:::i;:::-;7878:88;;7694:278;7632:340;;;;:::o;7978:509::-;8047:6;8096:2;8084:9;8075:7;8071:23;8067:32;8064:119;;;8102:79;;:::i;:::-;8064:119;8250:1;8239:9;8235:17;8222:31;8280:18;8272:6;8269:30;8266:117;;;8302:79;;:::i;:::-;8266:117;8407:63;8462:7;8453:6;8442:9;8438:22;8407:63;:::i;:::-;8397:73;;8193:287;7978:509;;;;:::o;8493:329::-;8552:6;8601:2;8589:9;8580:7;8576:23;8572:32;8569:119;;;8607:79;;:::i;:::-;8569:119;8727:1;8752:53;8797:7;8788:6;8777:9;8773:22;8752:53;:::i;:::-;8742:63;;8698:117;8493:329;;;;:::o;8828:117::-;8937:1;8934;8927:12;8951:117;9060:1;9057;9050:12;9091:568;9164:8;9174:6;9224:3;9217:4;9209:6;9205:17;9201:27;9191:122;;9232:79;;:::i;:::-;9191:122;9345:6;9332:20;9322:30;;9375:18;9367:6;9364:30;9361:117;;;9397:79;;:::i;:::-;9361:117;9511:4;9503:6;9499:17;9487:29;;9565:3;9557:4;9549:6;9545:17;9535:8;9531:32;9528:41;9525:128;;;9572:79;;:::i;:::-;9525:128;9091:568;;;;;:::o;9665:704::-;9760:6;9768;9776;9825:2;9813:9;9804:7;9800:23;9796:32;9793:119;;;9831:79;;:::i;:::-;9793:119;9979:1;9968:9;9964:17;9951:31;10009:18;10001:6;9998:30;9995:117;;;10031:79;;:::i;:::-;9995:117;10144:80;10216:7;10207:6;10196:9;10192:22;10144:80;:::i;:::-;10126:98;;;;9922:312;10273:2;10299:53;10344:7;10335:6;10324:9;10320:22;10299:53;:::i;:::-;10289:63;;10244:118;9665:704;;;;;:::o;10375:474::-;10443:6;10451;10500:2;10488:9;10479:7;10475:23;10471:32;10468:119;;;10506:79;;:::i;:::-;10468:119;10626:1;10651:53;10696:7;10687:6;10676:9;10672:22;10651:53;:::i;:::-;10641:63;;10597:117;10753:2;10779:53;10824:7;10815:6;10804:9;10800:22;10779:53;:::i;:::-;10769:63;;10724:118;10375:474;;;;;:::o;10855:116::-;10925:21;10940:5;10925:21;:::i;:::-;10918:5;10915:32;10905:60;;10961:1;10958;10951:12;10905:60;10855:116;:::o;10977:133::-;11020:5;11058:6;11045:20;11036:29;;11074:30;11098:5;11074:30;:::i;:::-;10977:133;;;;:::o;11116:468::-;11181:6;11189;11238:2;11226:9;11217:7;11213:23;11209:32;11206:119;;;11244:79;;:::i;:::-;11206:119;11364:1;11389:53;11434:7;11425:6;11414:9;11410:22;11389:53;:::i;:::-;11379:63;;11335:117;11491:2;11517:50;11559:7;11550:6;11539:9;11535:22;11517:50;:::i;:::-;11507:60;;11462:115;11116:468;;;;;:::o;11590:307::-;11651:4;11741:18;11733:6;11730:30;11727:56;;;11763:18;;:::i;:::-;11727:56;11801:29;11823:6;11801:29;:::i;:::-;11793:37;;11885:4;11879;11875:15;11867:23;;11590:307;;;:::o;11903:423::-;11980:5;12005:65;12021:48;12062:6;12021:48;:::i;:::-;12005:65;:::i;:::-;11996:74;;12093:6;12086:5;12079:21;12131:4;12124:5;12120:16;12169:3;12160:6;12155:3;12151:16;12148:25;12145:112;;;12176:79;;:::i;:::-;12145:112;12266:54;12313:6;12308:3;12303;12266:54;:::i;:::-;11986:340;11903:423;;;;;:::o;12345:338::-;12400:5;12449:3;12442:4;12434:6;12430:17;12426:27;12416:122;;12457:79;;:::i;:::-;12416:122;12574:6;12561:20;12599:78;12673:3;12665:6;12658:4;12650:6;12646:17;12599:78;:::i;:::-;12590:87;;12406:277;12345:338;;;;:::o;12689:943::-;12784:6;12792;12800;12808;12857:3;12845:9;12836:7;12832:23;12828:33;12825:120;;;12864:79;;:::i;:::-;12825:120;12984:1;13009:53;13054:7;13045:6;13034:9;13030:22;13009:53;:::i;:::-;12999:63;;12955:117;13111:2;13137:53;13182:7;13173:6;13162:9;13158:22;13137:53;:::i;:::-;13127:63;;13082:118;13239:2;13265:53;13310:7;13301:6;13290:9;13286:22;13265:53;:::i;:::-;13255:63;;13210:118;13395:2;13384:9;13380:18;13367:32;13426:18;13418:6;13415:30;13412:117;;;13448:79;;:::i;:::-;13412:117;13553:62;13607:7;13598:6;13587:9;13583:22;13553:62;:::i;:::-;13543:72;;13338:287;12689:943;;;;;;;:::o;13638:474::-;13706:6;13714;13763:2;13751:9;13742:7;13738:23;13734:32;13731:119;;;13769:79;;:::i;:::-;13731:119;13889:1;13914:53;13959:7;13950:6;13939:9;13935:22;13914:53;:::i;:::-;13904:63;;13860:117;14016:2;14042:53;14087:7;14078:6;14067:9;14063:22;14042:53;:::i;:::-;14032:63;;13987:118;13638:474;;;;;:::o;14118:180::-;14166:77;14163:1;14156:88;14263:4;14260:1;14253:15;14287:4;14284:1;14277:15;14304:320;14348:6;14385:1;14379:4;14375:12;14365:22;;14432:1;14426:4;14422:12;14453:18;14443:81;;14509:4;14501:6;14497:17;14487:27;;14443:81;14571:2;14563:6;14560:14;14540:18;14537:38;14534:84;;14590:18;;:::i;:::-;14534:84;14355:269;14304:320;;;:::o;14630:141::-;14679:4;14702:3;14694:11;;14725:3;14722:1;14715:14;14759:4;14756:1;14746:18;14738:26;;14630:141;;;:::o;14777:93::-;14814:6;14861:2;14856;14849:5;14845:14;14841:23;14831:33;;14777:93;;;:::o;14876:107::-;14920:8;14970:5;14964:4;14960:16;14939:37;;14876:107;;;;:::o;14989:393::-;15058:6;15108:1;15096:10;15092:18;15131:97;15161:66;15150:9;15131:97;:::i;:::-;15249:39;15279:8;15268:9;15249:39;:::i;:::-;15237:51;;15321:4;15317:9;15310:5;15306:21;15297:30;;15370:4;15360:8;15356:19;15349:5;15346:30;15336:40;;15065:317;;14989:393;;;;;:::o;15388:60::-;15416:3;15437:5;15430:12;;15388:60;;;:::o;15454:142::-;15504:9;15537:53;15555:34;15564:24;15582:5;15564:24;:::i;:::-;15555:34;:::i;:::-;15537:53;:::i;:::-;15524:66;;15454:142;;;:::o;15602:75::-;15645:3;15666:5;15659:12;;15602:75;;;:::o;15683:269::-;15793:39;15824:7;15793:39;:::i;:::-;15854:91;15903:41;15927:16;15903:41;:::i;:::-;15895:6;15888:4;15882:11;15854:91;:::i;:::-;15848:4;15841:105;15759:193;15683:269;;;:::o;15958:73::-;16003:3;15958:73;:::o;16037:189::-;16114:32;;:::i;:::-;16155:65;16213:6;16205;16199:4;16155:65;:::i;:::-;16090:136;16037:189;;:::o;16232:186::-;16292:120;16309:3;16302:5;16299:14;16292:120;;;16363:39;16400:1;16393:5;16363:39;:::i;:::-;16336:1;16329:5;16325:13;16316:22;;16292:120;;;16232:186;;:::o;16424:543::-;16525:2;16520:3;16517:11;16514:446;;;16559:38;16591:5;16559:38;:::i;:::-;16643:29;16661:10;16643:29;:::i;:::-;16633:8;16629:44;16826:2;16814:10;16811:18;16808:49;;;16847:8;16832:23;;16808:49;16870:80;16926:22;16944:3;16926:22;:::i;:::-;16916:8;16912:37;16899:11;16870:80;:::i;:::-;16529:431;;16514:446;16424:543;;;:::o;16973:117::-;17027:8;17077:5;17071:4;17067:16;17046:37;;16973:117;;;;:::o;17096:169::-;17140:6;17173:51;17221:1;17217:6;17209:5;17206:1;17202:13;17173:51;:::i;:::-;17169:56;17254:4;17248;17244:15;17234:25;;17147:118;17096:169;;;;:::o;17270:295::-;17346:4;17492:29;17517:3;17511:4;17492:29;:::i;:::-;17484:37;;17554:3;17551:1;17547:11;17541:4;17538:21;17530:29;;17270:295;;;;:::o;17570:1395::-;17687:37;17720:3;17687:37;:::i;:::-;17789:18;17781:6;17778:30;17775:56;;;17811:18;;:::i;:::-;17775:56;17855:38;17887:4;17881:11;17855:38;:::i;:::-;17940:67;18000:6;17992;17986:4;17940:67;:::i;:::-;18034:1;18058:4;18045:17;;18090:2;18082:6;18079:14;18107:1;18102:618;;;;18764:1;18781:6;18778:77;;;18830:9;18825:3;18821:19;18815:26;18806:35;;18778:77;18881:67;18941:6;18934:5;18881:67;:::i;:::-;18875:4;18868:81;18737:222;18072:887;;18102:618;18154:4;18150:9;18142:6;18138:22;18188:37;18220:4;18188:37;:::i;:::-;18247:1;18261:208;18275:7;18272:1;18269:14;18261:208;;;18354:9;18349:3;18345:19;18339:26;18331:6;18324:42;18405:1;18397:6;18393:14;18383:24;;18452:2;18441:9;18437:18;18424:31;;18298:4;18295:1;18291:12;18286:17;;18261:208;;;18497:6;18488:7;18485:19;18482:179;;;18555:9;18550:3;18546:19;18540:26;18598:48;18640:4;18632:6;18628:17;18617:9;18598:48;:::i;:::-;18590:6;18583:64;18505:156;18482:179;18707:1;18703;18695:6;18691:14;18687:22;18681:4;18674:36;18109:611;;;18072:887;;17662:1303;;;17570:1395;;:::o;18971:147::-;19072:11;19109:3;19094:18;;18971:147;;;;:::o;19124:114::-;;:::o;19244:398::-;19403:3;19424:83;19505:1;19500:3;19424:83;:::i;:::-;19417:90;;19516:93;19605:3;19516:93;:::i;:::-;19634:1;19629:3;19625:11;19618:18;;19244:398;;;:::o;19648:379::-;19832:3;19854:147;19997:3;19854:147;:::i;:::-;19847:154;;20018:3;20011:10;;19648:379;;;:::o;20033:180::-;20081:77;20078:1;20071:88;20178:4;20175:1;20168:15;20202:4;20199:1;20192:15;20219:180;20267:77;20264:1;20257:88;20364:4;20361:1;20354:15;20388:4;20385:1;20378:15;20405:233;20444:3;20467:24;20485:5;20467:24;:::i;:::-;20458:33;;20513:66;20506:5;20503:77;20500:103;;20583:18;;:::i;:::-;20500:103;20630:1;20623:5;20619:13;20612:20;;20405:233;;;:::o;20644:164::-;20784:16;20780:1;20772:6;20768:14;20761:40;20644:164;:::o;20814:366::-;20956:3;20977:67;21041:2;21036:3;20977:67;:::i;:::-;20970:74;;21053:93;21142:3;21053:93;:::i;:::-;21171:2;21166:3;21162:12;21155:19;;20814:366;;;:::o;21186:419::-;21352:4;21390:2;21379:9;21375:18;21367:26;;21439:9;21433:4;21429:20;21425:1;21414:9;21410:17;21403:47;21467:131;21593:4;21467:131;:::i;:::-;21459:139;;21186:419;;;:::o;21611:148::-;21713:11;21750:3;21735:18;;21611:148;;;;:::o;21765:390::-;21871:3;21899:39;21932:5;21899:39;:::i;:::-;21954:89;22036:6;22031:3;21954:89;:::i;:::-;21947:96;;22052:65;22110:6;22105:3;22098:4;22091:5;22087:16;22052:65;:::i;:::-;22142:6;22137:3;22133:16;22126:23;;21875:280;21765:390;;;;:::o;22185:874::-;22288:3;22325:5;22319:12;22354:36;22380:9;22354:36;:::i;:::-;22406:89;22488:6;22483:3;22406:89;:::i;:::-;22399:96;;22526:1;22515:9;22511:17;22542:1;22537:166;;;;22717:1;22712:341;;;;22504:549;;22537:166;22621:4;22617:9;22606;22602:25;22597:3;22590:38;22683:6;22676:14;22669:22;22661:6;22657:35;22652:3;22648:45;22641:52;;22537:166;;22712:341;22779:38;22811:5;22779:38;:::i;:::-;22839:1;22853:154;22867:6;22864:1;22861:13;22853:154;;;22941:7;22935:14;22931:1;22926:3;22922:11;22915:35;22991:1;22982:7;22978:15;22967:26;;22889:4;22886:1;22882:12;22877:17;;22853:154;;;23036:6;23031:3;23027:16;23020:23;;22719:334;;22504:549;;22292:767;;22185:874;;;;:::o;23065:589::-;23290:3;23312:95;23403:3;23394:6;23312:95;:::i;:::-;23305:102;;23424:95;23515:3;23506:6;23424:95;:::i;:::-;23417:102;;23536:92;23624:3;23615:6;23536:92;:::i;:::-;23529:99;;23645:3;23638:10;;23065:589;;;;;;:::o;23660:171::-;23699:3;23722:24;23740:5;23722:24;:::i;:::-;23713:33;;23768:4;23761:5;23758:15;23755:41;;23776:18;;:::i;:::-;23755:41;23823:1;23816:5;23812:13;23805:20;;23660:171;;;:::o;23837:181::-;23977:33;23973:1;23965:6;23961:14;23954:57;23837:181;:::o;24024:366::-;24166:3;24187:67;24251:2;24246:3;24187:67;:::i;:::-;24180:74;;24263:93;24352:3;24263:93;:::i;:::-;24381:2;24376:3;24372:12;24365:19;;24024:366;;;:::o;24396:419::-;24562:4;24600:2;24589:9;24585:18;24577:26;;24649:9;24643:4;24639:20;24635:1;24624:9;24620:17;24613:47;24677:131;24803:4;24677:131;:::i;:::-;24669:139;;24396:419;;;:::o;24821:98::-;24872:6;24906:5;24900:12;24890:22;;24821:98;;;:::o;24925:168::-;25008:11;25042:6;25037:3;25030:19;25082:4;25077:3;25073:14;25058:29;;24925:168;;;;:::o;25099:373::-;25185:3;25213:38;25245:5;25213:38;:::i;:::-;25267:70;25330:6;25325:3;25267:70;:::i;:::-;25260:77;;25346:65;25404:6;25399:3;25392:4;25385:5;25381:16;25346:65;:::i;:::-;25436:29;25458:6;25436:29;:::i;:::-;25431:3;25427:39;25420:46;;25189:283;25099:373;;;;:::o;25478:640::-;25673:4;25711:3;25700:9;25696:19;25688:27;;25725:71;25793:1;25782:9;25778:17;25769:6;25725:71;:::i;:::-;25806:72;25874:2;25863:9;25859:18;25850:6;25806:72;:::i;:::-;25888;25956:2;25945:9;25941:18;25932:6;25888:72;:::i;:::-;26007:9;26001:4;25997:20;25992:2;25981:9;25977:18;25970:48;26035:76;26106:4;26097:6;26035:76;:::i;:::-;26027:84;;25478:640;;;;;;;:::o;26124:141::-;26180:5;26211:6;26205:13;26196:22;;26227:32;26253:5;26227:32;:::i;:::-;26124:141;;;;:::o;26271:349::-;26340:6;26389:2;26377:9;26368:7;26364:23;26360:32;26357:119;;;26395:79;;:::i;:::-;26357:119;26515:1;26540:63;26595:7;26586:6;26575:9;26571:22;26540:63;:::i;:::-;26530:73;;26486:127;26271:349;;;;:::o;26626:180::-;26674:77;26671:1;26664:88;26771:4;26768:1;26761:15;26795:4;26792:1;26785:15

Swarm Source

ipfs://60e5f718fe453b0fd3c049dd9976b2a51868ab0ccabe7322ef3f0519189cb269
[ 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.