ETH Price: $2,631.60 (-1.29%)

MC Pet Carriers (CARRIER)
 

Overview

TokenID

917

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
MCPetCarriers

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 20000 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity Multiple files format)

File 17 of 21: MCPetCarriers.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
import "./ERC721ABurnable.sol";
import "./ERC721A.sol";
import "./Ownable.sol";
import "./Strings.sol";
import "./ReentrancyGuard.sol";
import {DefaultOperatorFilterer} from "./DefaultOperatorFilterer.sol";
contract OwnableDelegateProxy {}

/**
 * Used to delegate ownership of a contract to another address, to save on unneeded transactions to approve contract use for users
 */
contract ProxyRegistry {
    mapping(address => OwnableDelegateProxy) public proxies;
}

contract MCPetCarriers is ERC721ABurnable, DefaultOperatorFilterer, Ownable, ReentrancyGuard {
    using Strings for uint256;
    string public baseURI;
    uint256 public totalWithdrawn = 0;
    uint256 public maxSupply = 3000;
    uint256 public maxMint = 30; // max per transaction
    bool public claimingDisabled = false;
    bool public redeemingDisabled = true;
    bool public burningDisabled = true;

    address public constant MASTERCATS_CONTRACT = 0xF03c4e6b6187AcA96B18162CBb4468FC6E339120;
    address public constant MASTERCATS_VAULT = 0x7d0b3f2F241CaeDE2d6d885Bb6d7f149ecdfba24;
    address public constant SIGNER = 0x918de5F6A7411219D7ea785DCe2d5D6B120B2912;
    
    string _name = "MC Pet Carriers";
    string _symbol = "CARRIER";
    string _initBaseURI = "https://mastercatsnft.io:7777/api/tokens/carriers/";

    address public proxyRegistryAddress = 0xa5409ec958C83C3f309868babACA7c86DCB077c1; // OpenSea Mainnet Proxy Registry address
    
    constructor() ERC721A(_name, _symbol) {
        setBaseURI(_initBaseURI);
    }

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

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

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

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

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data)
        public
        payable
        override
        onlyAllowedOperator(from)
    {
        super.safeTransferFrom(from, to, tokenId, data);
    }
    
    /* claim signature verification */
    function recoverSigner(bytes32 _ethSignedMessageHash, bytes memory _signature) private pure returns (address) {
        (bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature);
        return ecrecover(_ethSignedMessageHash, v, r, s);
    }
    
    function splitSignature(bytes memory sig) private pure returns (bytes32 r, bytes32 s, uint8 v) {
        require(sig.length == 65, "Invalid signature length");
        assembly {
            r := mload(add(sig, 32))
            s := mload(add(sig, 64))
            v := byte(0, mload(add(sig, 96)))
        }
    }

    function checkClaimSignature(address user, bytes memory signature, uint256 userMaxAllowance) public pure returns (bool) {
        bytes32 messageHash = keccak256(abi.encodePacked(user, userMaxAllowance));
        bytes32 ethSignedMessageHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", messageHash));
        return recoverSigner(ethSignedMessageHash, signature) == SIGNER;
    }

    function checkRedeemSignature(address user, bytes memory signature, uint256[] calldata carrierIds, uint256[] calldata catIds) public pure returns (bool) {
        bytes32 messageHash = keccak256(abi.encodePacked(carrierIds, user, catIds));
        bytes32 ethSignedMessageHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", messageHash));
        return recoverSigner(ethSignedMessageHash, signature) == SIGNER;
    }

    // public redeem (burn) pet carrier to receive cat - requires signature
    function redeemCarrier(uint256[] calldata carrierIds, uint256[] calldata catIds, bytes memory signature) external nonReentrant {
        require(!redeemingDisabled, "Redeeming has been disabled");
        require(carrierIds.length == catIds.length, "Invalid carrierIds and catIds (length mismatch)");
        require(checkRedeemSignature(msg.sender, signature, carrierIds, catIds), "Signature invalid"); // verifies the carrier & cat ids
        for(uint256 i = 0; i < carrierIds.length; ++i) {
            _burn(carrierIds[i], true); // will fail if user does not own carrier/is not approved
            IERC721A(MASTERCATS_CONTRACT).safeTransferFrom(MASTERCATS_VAULT, msg.sender, catIds[i]); // will fail if the vault does not own the cat
        }
    }

    // public claim pet carrier - requires signature
    function claimCarrier(uint256 userMaxAllowance, uint256 claimQty, bytes memory signature) external nonReentrant {
        require(!claimingDisabled, "Claiming has been disabled");
        require(checkClaimSignature(msg.sender, signature, userMaxAllowance), "Signature invalid"); // verifies their allowance
        uint256 userMinted = _numberMinted(msg.sender); // qty user has minted
        uint256 userCanMint = userMaxAllowance - userMinted; // qty user can mint based on existing mints and their allowance
        // restrict to maxMint limit per tx
        if(userCanMint > maxMint) {
            userCanMint = maxMint;
        }
        // restrict to max user can mint
        if(claimQty > userCanMint) {
            claimQty = userCanMint;
        }
        uint256 supply = _totalMinted(); // total minted globally
        require((supply + claimQty) <= maxSupply, "Exceeds max supply");
        _mint(msg.sender, claimQty);
        delete supply;
        delete userMinted;
        delete userCanMint;
    }

    // admin minting
    function adminClaimCarrier(uint256[] calldata quantities, address[] calldata recipients) external onlyOwner {
        require(quantities.length == recipients.length, "Invalid quantities and recipients (length mismatch)");
        uint256 totalQuantity = 0;
        uint256 supply = _totalMinted(); // total minted globally
        for (uint256 i = 0; i < quantities.length; ++i) {
            totalQuantity += quantities[i];
        }
        require(supply + totalQuantity <= maxSupply, "Exceeds max mupply");
        delete totalQuantity;
        for (uint256 i = 0; i < recipients.length; ++i) {
            _mint(recipients[i], quantities[i]);
        }
        delete supply;
    }

    function burn(uint256 tokenId) public virtual override {
        require(!burningDisabled, "Burning is disabled");
        _burn(tokenId, true);
    }

    function batchTransferFrom(address _from, address _to, uint256[] memory _tokenIds) public {
        for (uint256 i = 0; i < _tokenIds.length; i++) {
            transferFrom(_from, _to, _tokenIds[i]);
        }
    }

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

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: Nonexistent token");
        string memory currentBaseURI = _baseURI();
        return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(currentBaseURI, tokenId.toString())) : "";
    }

    function setMaxMint(uint256 _maxMint) public onlyOwner {
        maxMint = _maxMint;
    }

    function setMaxSupply(uint256 _newMaxSupply) public onlyOwner {
        maxSupply = _newMaxSupply;
    }

    function setBaseURI(string memory _newBaseURI) public onlyOwner {
        baseURI = _newBaseURI;
    }

    function setClaimingDisabled(bool _claimingDisabled) public onlyOwner {
        claimingDisabled = _claimingDisabled;
    }

    function setRedeemingDisabled(bool _redeemingDisabled) public onlyOwner {
        redeemingDisabled = _redeemingDisabled;
    }

    function setBurningDisabled(bool _burningDisabled) public onlyOwner {
        burningDisabled = _burningDisabled;
    }

    function totalMinted() public view returns (uint256) {
        return _totalMinted();
    }

    function numberMinted(address owner) public view returns (uint256) {
        return _numberMinted(owner);
    }

    function totalBurned() public view returns (uint256) {
        return _totalBurned();
    }

    function numberBurned(address owner) public view returns (uint256) {
        return _numberBurned(owner);
    }

    function ownershipOf(uint256 tokenId)
        external
        view
        returns (TokenOwnership memory)
    {
        return _ownershipOf(tokenId);
    }

    function getTotalWithdrawn() public view returns (uint256) {
        return totalWithdrawn;
    }

    function getTotalBalance() public view returns (uint256) {
        return address(this).balance;
    }

    function getTotalRaised() public view returns (uint256) {
        return getTotalWithdrawn() + getTotalBalance();
    }

    /**
     * withdraw ETH from the contract (callable by Owner only)
     */
    function withdraw() public payable onlyOwner {
        uint256 val = address(this).balance;
        (bool success, ) = payable(msg.sender).call{
            value: val
        }("");
        require(success);
        totalWithdrawn += val;
        delete val;
    }
    /**
     * whitelist user's OpenSea proxy accounts to enable gas-less listings.
     */
    function isApprovedForAll(address owner, address operator) override public view returns (bool) {
        // Whitelist OpenSea proxy contract for easy trading.
        ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
        if (address(proxyRegistry.proxies(owner)) == operator) {
            return true;
        }
        return super.isApprovedForAll(owner, operator);
    }
}

File 1 of 21: Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/Address.sol)

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 2 of 21: Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

File 3 of 21: DefaultOperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import {OperatorFilterer} from "./OperatorFilterer.sol";

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

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

File 4 of 21: ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 5 of 21: ERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721A.sol';

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        return _tokenApprovals[tokenId].value;
    }

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfers(from, to, tokenId, 1);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        address from = address(uint160(prevOwnershipPacked));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 6 of 21: ERC721ABurnable.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721ABurnable.sol';
import './ERC721A.sol';

/**
 * @title ERC721ABurnable.
 *
 * @dev ERC721A token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721ABurnable is ERC721A, IERC721ABurnable {
    /**
     * @dev Burns `tokenId`. See {ERC721A-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual override {
        _burn(tokenId, true);
    }
}

File 7 of 21: ERC721Enum.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.10;
import "./ERC721P.sol";
import "./IERC721Enumerable.sol";

abstract contract ERC721Enum is ERC721P, IERC721Enumerable {
    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(IERC165, ERC721P)
        returns (bool)
    {
        return
            interfaceId == type(IERC721Enumerable).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    function tokenOfOwnerByIndex(address owner, uint256 index)
        public
        view
        override
        returns (uint256 tokenId)
    {
        require(index < ERC721P.balanceOf(owner), "ERC721Enum: owner ioob");
        uint256 count;
        for (uint256 i; i < _owners.length; ++i) {
            if (owner == _owners[i]) {
                if (count == index) return i;
                else ++count;
            }
        }
        require(false, "ERC721Enum: owner ioob");
    }

    function tokensOfOwner(address owner)
        public
        view
        returns (uint256[] memory)
    {
        require(0 < ERC721P.balanceOf(owner), "ERC721Enum: owner ioob");
        uint256 tokenCount = balanceOf(owner);
        uint256[] memory tokenIds = new uint256[](tokenCount);
        for (uint256 i = 0; i < tokenCount; i++) {
            tokenIds[i] = tokenOfOwnerByIndex(owner, i);
        }
        return tokenIds;
    }

    function totalSupply() public view virtual override returns (uint256) {
        return _owners.length;
    }

    function tokenByIndex(uint256 index)
        public
        view
        virtual
        override
        returns (uint256)
    {
        require(index < ERC721Enum.totalSupply(), "ERC721Enum: global ioob");
        return index;
    }
}

File 8 of 21: ERC721P.sol
// SPDX-License-Identifier: GPL-3.0

// Thank you to ToyBoogers & Pagzi Tech for the optimised ERC721
pragma solidity ^0.8.10;
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./IERC721Metadata.sol";
import "./Address.sol";
import "./Context.sol";
import "./ERC165.sol";

abstract contract ERC721P is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    string private _name;
    string private _symbol;
    address[] internal _owners;
    mapping(uint256 => address) private _tokenApprovals;
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }
    
    function getOwners() external view returns (address[] memory) {
        return _owners;
    }

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

    function balanceOf(address owner)
        public
        view
        virtual
        override
        returns (uint256)
    {
        require(
            owner != address(0),
            "ERC721: balance query for the zero address"
        );
        uint256 count = 0;
        uint256 length = _owners.length;
        for (uint256 i = 0; i < length; ++i) {
            if (owner == _owners[i]) {
                ++count;
            }
        }
        delete length;
        return count;
    }

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

    function name() public view virtual override returns (string memory) {
        return _name;
    }

    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721P.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

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

        _approve(to, tokenId);
    }

    function getApproved(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        require(
            _exists(tokenId),
            "ERC721: approved query for nonexistent token"
        );

        return _tokenApprovals[tokenId];
    }

    function setApprovalForAll(address operator, bool approved)
        public
        virtual
        override
    {
        require(operator != _msgSender(), "ERC721: approve to caller");

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

    function isApprovedForAll(address owner, address operator)
        public
        view
        virtual
        override
        returns (bool)
    {
        return _operatorApprovals[owner][operator];
    }

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

        _transfer(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

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

    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(
            _checkOnERC721Received(from, to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return tokenId < _owners.length && _owners[tokenId] != address(0);
    }

    function _isApprovedOrOwner(address spender, uint256 tokenId)
        internal
        view
        virtual
        returns (bool)
    {
        require(
            _exists(tokenId),
            "ERC721: operator query for nonexistent token"
        );
        address owner = ERC721P.ownerOf(tokenId);
        return (spender == owner ||
            getApproved(tokenId) == spender ||
            isApprovedForAll(owner, spender));
    }

    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);
        _owners.push(to);

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

    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721P.ownerOf(tokenId);

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

        // Clear approvals
        _approve(address(0), tokenId);
        _owners[tokenId] = address(0);

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

    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(
            ERC721P.ownerOf(tokenId) == from,
            "ERC721: transfer of token that is not own"
        );
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721P.ownerOf(tokenId), to, tokenId);
    }

    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try
                IERC721Receiver(to).onERC721Received(
                    _msgSender(),
                    from,
                    tokenId,
                    _data
                )
            returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert(
                        "ERC721: transfer to non ERC721Receiver implementer"
                    );
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

File 9 of 21: IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

File 10 of 21: IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

File 11 of 21: IERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 12 of 21: IERC721ABurnable.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721A.sol';

/**
 * @dev Interface of ERC721ABurnable.
 */
interface IERC721ABurnable is IERC721A {
    /**
     * @dev Burns `tokenId`. See {ERC721A-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) external;
}

File 13 of 21: IERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

import "./IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

File 14 of 21: IERC721Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

import "./IERC721.sol";

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

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

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

File 15 of 21: IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

File 16 of 21: IOperatorFilterRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

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

File 18 of 21: OperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";

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

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

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

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

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

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

File 19 of 21: Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "./Context.sol";

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

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

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

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

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

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

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

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

File 20 of 21: ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.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() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

        _;

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

File 21 of 21: Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MASTERCATS_CONTRACT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MASTERCATS_VAULT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SIGNER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"quantities","type":"uint256[]"},{"internalType":"address[]","name":"recipients","type":"address[]"}],"name":"adminClaimCarrier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"batchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burningDisabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256","name":"userMaxAllowance","type":"uint256"}],"name":"checkClaimSignature","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256[]","name":"carrierIds","type":"uint256[]"},{"internalType":"uint256[]","name":"catIds","type":"uint256[]"}],"name":"checkRedeemSignature","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"userMaxAllowance","type":"uint256"},{"internalType":"uint256","name":"claimQty","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"claimCarrier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimingDisabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalRaised","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalWithdrawn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"numberBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxyRegistryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"carrierIds","type":"uint256[]"},{"internalType":"uint256[]","name":"catIds","type":"uint256[]"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"redeemCarrier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redeemingDisabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_burningDisabled","type":"bool"}],"name":"setBurningDisabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_claimingDisabled","type":"bool"}],"name":"setClaimingDisabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxMint","type":"uint256"}],"name":"setMaxMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_redeemingDisabled","type":"bool"}],"name":"setRedeemingDisabled","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":"totalBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWithdrawn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]

6000600b55610bb8600c55601e600d55600e805462ffffff19166201010017905560c0604052600f60808190526e4d432050657420436172726965727360881b60a0908152620000519190816200051f565b506040805180820190915260078082526621a0a92924a2a960c91b602090920191825262000082916010916200051f565b5060405180606001604052806032815260200162003dbb603291398051620000b3916011916020909101906200051f565b50601280546001600160a01b03191673a5409ec958c83c3f309868babaca7c86dcb077c1179055348015620000e757600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb66001600f80546200010e90620005c5565b80601f01602080910402602001604051908101604052809291908181526020018280546200013c90620005c5565b80156200018d5780601f1062000161576101008083540402835291602001916200018d565b820191906000526020600020905b8154815290600101906020018083116200016f57829003601f168201915b505050505060108054620001a190620005c5565b80601f0160208091040260200160405190810160405280929190818152602001828054620001cf90620005c5565b8015620002205780601f10620001f45761010080835404028352916020019162000220565b820191906000526020600020905b8154815290600101906020018083116200020257829003601f168201915b505084516200023a9350600292506020860191506200051f565b508051620002509060039060208401906200051f565b506000805550506daaeb6d7670e522a718067333cd4e3b156200039c578015620002ea57604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b158015620002cb57600080fd5b505af1158015620002e0573d6000803e3d6000fd5b505050506200039c565b6001600160a01b038216156200033b5760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af290390604401620002b0565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b1580156200038257600080fd5b505af115801562000397573d6000803e3d6000fd5b505050505b50620003aa90503362000455565b6001600955601180546200044f9190620003c490620005c5565b80601f0160208091040260200160405190810160405280929190818152602001828054620003f290620005c5565b8015620004435780601f10620004175761010080835404028352916020019162000443565b820191906000526020600020905b8154815290600101906020018083116200042557829003601f168201915b5050620004a792505050565b62000602565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6008546001600160a01b03163314620005065760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640160405180910390fd5b80516200051b90600a9060208401906200051f565b5050565b8280546200052d90620005c5565b90600052602060002090601f0160209004810192826200055157600085556200059c565b82601f106200056c57805160ff19168380011785556200059c565b828001600101855582156200059c579182015b828111156200059c5782518255916020019190600101906200057f565b50620005aa929150620005ae565b5090565b5b80821115620005aa5760008155600101620005af565b600181811c90821680620005da57607f821691505b60208210811415620005fc57634e487b7160e01b600052602260045260246000fd5b50919050565b6137a980620006126000396000f3fe6080604052600436106103345760003560e01c80636c0360eb116101b0578063b88d4fde116100ec578063d89135cd11610095578063f2a452981161006f578063f2a452981461091b578063f2fde38b1461093b578063f3993d111461095b578063fe3dbd811461097b57600080fd5b8063d89135cd146108c6578063dc33e681146108db578063e985e9c5146108fb57600080fd5b8063ce3dc5cf116100c6578063ce3dc5cf14610870578063d50e003614610890578063d5abeb01146108b057600080fd5b8063b88d4fde14610810578063c87b56dd14610823578063cd7c03261461084357600080fd5b80638da5cb5b116101595780639f550293116101335780639f550293146107a7578063a22cb465146107bc578063a2309ff8146107dc578063a7b7f222146107f157600080fd5b80638da5cb5b1461074757806395d89b411461077257806399edf7eb1461078757600080fd5b8063715018a61161018a578063715018a6146107075780637501f7411461071c57806389404a791461073257600080fd5b80636c0360eb146106b25780636f8b44b0146106c757806370a08231146106e757600080fd5b80633ccfd60b1161027f57806342966c6811610228578063547520fe11610202578063547520fe1461062a57806355f804b31461064a578063582abd121461066a5780636352211e1461069257600080fd5b806342966c68146105cc578063468f87f2146105ec5780634b3197131461061457600080fd5b80634193cdf8116102595780634193cdf81461057757806341f434341461059757806342842e0e146105b957600080fd5b80633ccfd60b146105275780633d43675a1461052f5780634121555e1461054f57600080fd5b806318160ddd116102e15780632478d639116102bb5780632478d639146104cd578063285e61d1146104ed57806332b9de9a1461050d57600080fd5b806318160ddd1461048157806323b872dd1461049a57806323d2bf1e146104ad57600080fd5b8063095ea7b311610312578063095ea7b3146103d557806312b58349146103ea578063140364a11461040757600080fd5b806301ffc9a71461033957806306fdde031461036e578063081812fc14610390575b600080fd5b34801561034557600080fd5b50610359610354366004612d6f565b61099b565b60405190151581526020015b60405180910390f35b34801561037a57600080fd5b50610383610a80565b6040516103659190612e02565b34801561039c57600080fd5b506103b06103ab366004612e15565b610b12565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610365565b6103e86103e3366004612e50565b610b7c565b005b3480156103f657600080fd5b50475b604051908152602001610365565b34801561041357600080fd5b50610427610422366004612e15565b610b95565b6040516103659190815173ffffffffffffffffffffffffffffffffffffffff16815260208083015167ffffffffffffffff169082015260408083015115159082015260609182015162ffffff169181019190915260800190565b34801561048d57600080fd5b50600154600054036103f9565b6103e86104a8366004612e7c565b610bc2565b3480156104b957600080fd5b506103e86104c8366004612ecb565b610bfa565b3480156104d957600080fd5b506103f96104e8366004612ee8565b610c97565b3480156104f957600080fd5b50610359610508366004613019565b610cd2565b34801561051957600080fd5b50600e546103599060ff1681565b6103e8610dd5565b34801561053b57600080fd5b506103e861054a366004612ecb565b610eae565b34801561055b57600080fd5b506103b0737d0b3f2f241caede2d6d885bb6d7f149ecdfba2481565b34801561058357600080fd5b506103e86105923660046130be565b610f4d565b3480156105a357600080fd5b506103b06daaeb6d7670e522a718067333cd4e81565b6103e86105c7366004612e7c565b6111ee565b3480156105d857600080fd5b506103e86105e7366004612e15565b611220565b3480156105f857600080fd5b506103b073f03c4e6b6187aca96b18162cbb4468fc6e33912081565b34801561062057600080fd5b506103f9600b5481565b34801561063657600080fd5b506103e8610645366004612e15565b611287565b34801561065657600080fd5b506103e8610665366004613152565b6112f3565b34801561067657600080fd5b506103b073918de5f6a7411219d7ea785dce2d5d6b120b291281565b34801561069e57600080fd5b506103b06106ad366004612e15565b611371565b3480156106be57600080fd5b5061038361137c565b3480156106d357600080fd5b506103e86106e2366004612e15565b61140a565b3480156106f357600080fd5b506103f9610702366004612ee8565b611476565b34801561071357600080fd5b506103e86114f8565b34801561072857600080fd5b506103f9600d5481565b34801561073e57600080fd5b50600b546103f9565b34801561075357600080fd5b5060085473ffffffffffffffffffffffffffffffffffffffff166103b0565b34801561077e57600080fd5b5061038361156b565b34801561079357600080fd5b506103e86107a2366004612ecb565b61157a565b3480156107b357600080fd5b506103f9611618565b3480156107c857600080fd5b506103e86107d736600461319b565b61162d565b3480156107e857600080fd5b506000546103f9565b3480156107fd57600080fd5b50600e5461035990610100900460ff1681565b6103e861081e3660046131d4565b611641565b34801561082f57600080fd5b5061038361083e366004612e15565b61167b565b34801561084f57600080fd5b506012546103b09073ffffffffffffffffffffffffffffffffffffffff1681565b34801561087c57600080fd5b506103e861088b366004613240565b611754565b34801561089c57600080fd5b506103596108ab366004613290565b611903565b3480156108bc57600080fd5b506103f9600c5481565b3480156108d257600080fd5b506103f96119e7565b3480156108e757600080fd5b506103f96108f6366004612ee8565b6119f2565b34801561090757600080fd5b50610359610916366004613337565b611a2a565b34801561092757600080fd5b506103e8610936366004613365565b611b2b565b34801561094757600080fd5b506103e8610956366004612ee8565b611d22565b34801561096757600080fd5b506103e86109763660046133d1565b611e1b565b34801561098757600080fd5b50600e546103599062010000900460ff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083161480610a2e57507f80ac58cd000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b80610a7a57507f5b5e139f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b606060028054610a8f9061349e565b80601f0160208091040260200160405190810160405280929190818152602001828054610abb9061349e565b8015610b085780601f10610add57610100808354040283529160200191610b08565b820191906000526020600020905b815481529060010190602001808311610aeb57829003601f168201915b5050505050905090565b6000610b1d82611e5d565b610b53576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060009081526006602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b81610b8681611e9d565b610b908383611fa2565b505050565b604080516080810182526000808252602082018190529181018290526060810191909152610a7a8261208d565b8273ffffffffffffffffffffffffffffffffffffffff81163314610be957610be933611e9d565b610bf484848461212b565b50505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314610c665760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b600e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6000610a7a8273ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205460801c67ffffffffffffffff1690565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018290526000908190605401604051602081830303815290604052805190602001209050600081604051602001610d6791907f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b60405160208183030381529060405280519060200120905073918de5f6a7411219d7ea785dce2d5d6b120b291273ffffffffffffffffffffffffffffffffffffffff16610db482876123bd565b73ffffffffffffffffffffffffffffffffffffffff16149695505050505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314610e3c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b6040514790600090339083908381818185875af1925050503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5050905080610e9357600080fd5b81600b6000828254610ea59190613521565b90915550505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314610f155760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600e805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055565b60026009541415610fa05760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c5d565b6002600955600e54610100900460ff1615610ffd5760405162461bcd60e51b815260206004820152601b60248201527f52656465656d696e6720686173206265656e2064697361626c656400000000006044820152606401610c5d565b8382146110725760405162461bcd60e51b815260206004820152602f60248201527f496e76616c6964206361727269657249647320616e642063617449647320286c60448201527f656e677468206d69736d617463682900000000000000000000000000000000006064820152608401610c5d565b611080338287878787611903565b6110cc5760405162461bcd60e51b815260206004820152601160248201527f5369676e617475726520696e76616c69640000000000000000000000000000006044820152606401610c5d565b60005b848110156111e1576110fa8686838181106110ec576110ec613539565b90506020020135600161245a565b73f03c4e6b6187aca96b18162cbb4468fc6e3391206342842e0e737d0b3f2f241caede2d6d885bb6d7f149ecdfba243387878681811061113c5761113c613539565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e088901b16815273ffffffffffffffffffffffffffffffffffffffff958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b1580156111b857600080fd5b505af11580156111cc573d6000803e3d6000fd5b50505050806111da90613568565b90506110cf565b5050600160095550505050565b8273ffffffffffffffffffffffffffffffffffffffff811633146112155761121533611e9d565b610bf4848484612602565b600e5462010000900460ff16156112795760405162461bcd60e51b815260206004820152601360248201527f4275726e696e672069732064697361626c6564000000000000000000000000006044820152606401610c5d565b61128481600161245a565b50565b60085473ffffffffffffffffffffffffffffffffffffffff1633146112ee5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600d55565b60085473ffffffffffffffffffffffffffffffffffffffff16331461135a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b805161136d90600a906020840190612ca8565b5050565b6000610a7a8261261d565b600a80546113899061349e565b80601f01602080910402602001604051908101604052809291908181526020018280546113b59061349e565b80156114025780601f106113d757610100808354040283529160200191611402565b820191906000526020600020905b8154815290600101906020018083116113e557829003601f168201915b505050505081565b60085473ffffffffffffffffffffffffffffffffffffffff1633146114715760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600c55565b600073ffffffffffffffffffffffffffffffffffffffff82166114c5576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205467ffffffffffffffff1690565b60085473ffffffffffffffffffffffffffffffffffffffff16331461155f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b61156960006126ce565b565b606060038054610a8f9061349e565b60085473ffffffffffffffffffffffffffffffffffffffff1633146115e15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600e8054911515610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909216919091179055565b600047600b546116289190613521565b905090565b8161163781611e9d565b610b908383612745565b8373ffffffffffffffffffffffffffffffffffffffff811633146116685761166833611e9d565b611674858585856127dc565b5050505050565b606061168682611e5d565b6116f85760405162461bcd60e51b815260206004820152602160248201527f4552433732314d657461646174613a204e6f6e6578697374656e7420746f6b6560448201527f6e000000000000000000000000000000000000000000000000000000000000006064820152608401610c5d565b6000611702612846565b90506000815111611722576040518060200160405280600081525061174d565b8061172c84612855565b60405160200161173d9291906135a1565b6040516020818303038152906040525b9392505050565b600260095414156117a75760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c5d565b6002600955600e5460ff16156117ff5760405162461bcd60e51b815260206004820152601a60248201527f436c61696d696e6720686173206265656e2064697361626c65640000000000006044820152606401610c5d565b61180a338285610cd2565b6118565760405162461bcd60e51b815260206004820152601160248201527f5369676e617475726520696e76616c69640000000000000000000000000000006044820152606401610c5d565b3360009081526005602052604080822054901c67ffffffffffffffff169061187e82866135d0565b9050600d5481111561188f5750600d545b8084111561189b578093505b600054600c546118ab8683613521565b11156118f95760405162461bcd60e51b815260206004820152601260248201527f45786365656473206d617820737570706c7900000000000000000000000000006044820152606401610c5d565b6111e13386612987565b600080858589868660405160200161191f95949392919061362d565b60405160208183030381529060405280519060200120905060008160405160200161197691907f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b60405160208183030381529060405280519060200120905073918de5f6a7411219d7ea785dce2d5d6b120b291273ffffffffffffffffffffffffffffffffffffffff166119c3828a6123bd565b73ffffffffffffffffffffffffffffffffffffffff16149998505050505050505050565b600061162860015490565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600560205260408082205467ffffffffffffffff911c16610a7a565b6012546040517fc455279100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015260009281169190841690829063c455279190602401602060405180830381865afa158015611aa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac6919061367c565b73ffffffffffffffffffffffffffffffffffffffff161415611aec576001915050610a7a565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526007602090815260408083209387168352929052205460ff165b949350505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314611b925760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b828114611c075760405162461bcd60e51b815260206004820152603360248201527f496e76616c6964207175616e74697469657320616e6420726563697069656e7460448201527f7320286c656e677468206d69736d6174636829000000000000000000000000006064820152608401610c5d565b600080611c1360005490565b905060005b85811015611c5657868682818110611c3257611c32613539565b9050602002013583611c449190613521565b9250611c4f81613568565b9050611c18565b50600c54611c648383613521565b1115611cb25760405162461bcd60e51b815260206004820152601260248201527f45786365656473206d6178206d7570706c7900000000000000000000000000006044820152606401610c5d565b6000915060005b83811015611d1957611d09858583818110611cd657611cd6613539565b9050602002016020810190611ceb9190612ee8565b888884818110611cfd57611cfd613539565b90506020020135612987565b611d1281613568565b9050611cb9565b50505050505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314611d895760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b73ffffffffffffffffffffffffffffffffffffffff8116611e125760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610c5d565b611284816126ce565b60005b8151811015610bf457611e4b8484848481518110611e3e57611e3e613539565b6020026020010151610bc2565b80611e5581613568565b915050611e1e565b6000805482108015610a7a5750506000908152600460205260409020547c0100000000000000000000000000000000000000000000000000000000161590565b6daaeb6d7670e522a718067333cd4e3b15611284576040517fc617113400000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611f30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f549190613699565b611284576040517fede71dcc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610c5d565b6000611fad82611371565b90503373ffffffffffffffffffffffffffffffffffffffff82161461200c57611fd68133611a2a565b61200c576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b604080516080810182526000808252602082018190529181018290526060810191909152610a7a6120bd8361261d565b6040805160808101825273ffffffffffffffffffffffffffffffffffffffff8316815260a083901c67ffffffffffffffff1660208201527c0100000000000000000000000000000000000000000000000000000000831615159181019190915260e89190911c606082015290565b60006121368261261d565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461219d576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260066020526040902080546121d68187335b73ffffffffffffffffffffffffffffffffffffffff9081169116811491141790565b61221a576121e48633611a2a565b61221a576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516612267576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b801561227257600082555b73ffffffffffffffffffffffffffffffffffffffff86811660009081526005602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019055918716808252919020805460010190554260a01b177c0200000000000000000000000000000000000000000000000000000000176000858152600460205260409020557c0200000000000000000000000000000000000000000000000000000000831661235a57600184016000818152600460205260409020546123585760005481146123585760008181526004602052604090208490555b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b6000806000806123cc85612abe565b6040805160008152602081018083528b905260ff8316918101919091526060810184905260808101839052929550909350915060019060a0016020604051602081039080840390855afa158015612427573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151979650505050505050565b60006124658361261d565b90508060008061248386600090815260066020526040902080549091565b9150915084156124dc576124988184336121b4565b6124dc576124a68333611a2a565b6124dc576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80156124e757600082555b73ffffffffffffffffffffffffffffffffffffffff8316600081815260056020526040902080546fffffffffffffffffffffffffffffffff0190554260a01b177c0300000000000000000000000000000000000000000000000000000000176000878152600460205260409020557c020000000000000000000000000000000000000000000000000000000084166125ad57600186016000818152600460205260409020546125ab5760005481146125ab5760008181526004602052604090208590555b505b604051869060009073ffffffffffffffffffffffffffffffffffffffff8616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050600180548101905550505050565b610b9083838360405180602001604052806000815250611641565b60008160005481101561269c576000818152600460205260409020547c0100000000000000000000000000000000000000000000000000000000811661269a575b8061174d57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0160008181526004602052604090205461265e565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b33600081815260076020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6127e7848484610bc2565b73ffffffffffffffffffffffffffffffffffffffff83163b15610bf45761281084848484612b32565b610bf4576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6060600a8054610a8f9061349e565b60608161289557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156128bf57806128a981613568565b91506128b89050600a836136e5565b9150612899565b60008167ffffffffffffffff8111156128da576128da612f05565b6040519080825280601f01601f191660200182016040528015612904576020820181803683370190505b5090505b8415611b23576129196001836135d0565b9150612926600a866136f9565b612931906030613521565b60f81b81838151811061294657612946613539565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612980600a866136e5565b9450612908565b600054816129c1576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114612a7d57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101612a45565b5081612ab5576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005550505050565b60008060008351604114612b145760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207369676e6174757265206c656e67746800000000000000006044820152606401610c5d565b50505060208101516040820151606090920151909260009190911a90565b6040517f150b7a0200000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290612b8d90339089908890889060040161370d565b6020604051808303816000875af1925050508015612be6575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612be391810190613756565b60015b612c5a573d808015612c14576040519150601f19603f3d011682016040523d82523d6000602084013e612c19565b606091505b508051612c52576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050949350505050565b828054612cb49061349e565b90600052602060002090601f016020900481019282612cd65760008555612d1c565b82601f10612cef57805160ff1916838001178555612d1c565b82800160010185558215612d1c579182015b82811115612d1c578251825591602001919060010190612d01565b50612d28929150612d2c565b5090565b5b80821115612d285760008155600101612d2d565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461128457600080fd5b600060208284031215612d8157600080fd5b813561174d81612d41565b60005b83811015612da7578181015183820152602001612d8f565b83811115610bf45750506000910152565b60008151808452612dd0816020860160208601612d8c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061174d6020830184612db8565b600060208284031215612e2757600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461128457600080fd5b60008060408385031215612e6357600080fd5b8235612e6e81612e2e565b946020939093013593505050565b600080600060608486031215612e9157600080fd5b8335612e9c81612e2e565b92506020840135612eac81612e2e565b929592945050506040919091013590565b801515811461128457600080fd5b600060208284031215612edd57600080fd5b813561174d81612ebd565b600060208284031215612efa57600080fd5b813561174d81612e2e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612f7b57612f7b612f05565b604052919050565b600067ffffffffffffffff831115612f9d57612f9d612f05565b612fce60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601612f34565b9050828152838383011115612fe257600080fd5b828260208301376000602084830101529392505050565b600082601f83011261300a57600080fd5b61174d83833560208501612f83565b60008060006060848603121561302e57600080fd5b833561303981612e2e565b9250602084013567ffffffffffffffff81111561305557600080fd5b61306186828701612ff9565b925050604084013590509250925092565b60008083601f84011261308457600080fd5b50813567ffffffffffffffff81111561309c57600080fd5b6020830191508360208260051b85010111156130b757600080fd5b9250929050565b6000806000806000606086880312156130d657600080fd5b853567ffffffffffffffff808211156130ee57600080fd5b6130fa89838a01613072565b9097509550602088013591508082111561311357600080fd5b61311f89838a01613072565b9095509350604088013591508082111561313857600080fd5b5061314588828901612ff9565b9150509295509295909350565b60006020828403121561316457600080fd5b813567ffffffffffffffff81111561317b57600080fd5b8201601f8101841361318c57600080fd5b611b2384823560208401612f83565b600080604083850312156131ae57600080fd5b82356131b981612e2e565b915060208301356131c981612ebd565b809150509250929050565b600080600080608085870312156131ea57600080fd5b84356131f581612e2e565b9350602085013561320581612e2e565b925060408501359150606085013567ffffffffffffffff81111561322857600080fd5b61323487828801612ff9565b91505092959194509250565b60008060006060848603121561325557600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561327a57600080fd5b61328686828701612ff9565b9150509250925092565b600080600080600080608087890312156132a957600080fd5b86356132b481612e2e565b9550602087013567ffffffffffffffff808211156132d157600080fd5b6132dd8a838b01612ff9565b965060408901359150808211156132f357600080fd5b6132ff8a838b01613072565b9096509450606089013591508082111561331857600080fd5b5061332589828a01613072565b979a9699509497509295939492505050565b6000806040838503121561334a57600080fd5b823561335581612e2e565b915060208301356131c981612e2e565b6000806000806040858703121561337b57600080fd5b843567ffffffffffffffff8082111561339357600080fd5b61339f88838901613072565b909650945060208701359150808211156133b857600080fd5b506133c587828801613072565b95989497509550505050565b6000806000606084860312156133e657600080fd5b83356133f181612e2e565b925060208481013561340281612e2e565b9250604085013567ffffffffffffffff8082111561341f57600080fd5b818701915087601f83011261343357600080fd5b81358181111561344557613445612f05565b8060051b9150613456848301612f34565b818152918301840191848101908a84111561347057600080fd5b938501935b8385101561348e57843582529385019390850190613475565b8096505050505050509250925092565b600181811c908216806134b257607f821691505b602082108114156134ec577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115613534576135346134f2565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561359a5761359a6134f2565b5060010190565b600083516135b3818460208801612d8c565b8351908301906135c7818360208801612d8c565b01949350505050565b6000828210156135e2576135e26134f2565b500390565b60007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561361657600080fd5b8260051b8083863760009401938452509192915050565b600061363a8287896135e7565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008660601b1681526136706014820185876135e7565b98975050505050505050565b60006020828403121561368e57600080fd5b815161174d81612e2e565b6000602082840312156136ab57600080fd5b815161174d81612ebd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826136f4576136f46136b6565b500490565b600082613708576137086136b6565b500690565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261374c6080830184612db8565b9695505050505050565b60006020828403121561376857600080fd5b815161174d81612d4156fea2646970667358221220d41385961fb5df226d9a25f31d9e1621938c51c5053299c875de1ed2f946764764736f6c634300080a003368747470733a2f2f6d6173746572636174736e66742e696f3a373737372f6170692f746f6b656e732f63617272696572732f

Deployed Bytecode

0x6080604052600436106103345760003560e01c80636c0360eb116101b0578063b88d4fde116100ec578063d89135cd11610095578063f2a452981161006f578063f2a452981461091b578063f2fde38b1461093b578063f3993d111461095b578063fe3dbd811461097b57600080fd5b8063d89135cd146108c6578063dc33e681146108db578063e985e9c5146108fb57600080fd5b8063ce3dc5cf116100c6578063ce3dc5cf14610870578063d50e003614610890578063d5abeb01146108b057600080fd5b8063b88d4fde14610810578063c87b56dd14610823578063cd7c03261461084357600080fd5b80638da5cb5b116101595780639f550293116101335780639f550293146107a7578063a22cb465146107bc578063a2309ff8146107dc578063a7b7f222146107f157600080fd5b80638da5cb5b1461074757806395d89b411461077257806399edf7eb1461078757600080fd5b8063715018a61161018a578063715018a6146107075780637501f7411461071c57806389404a791461073257600080fd5b80636c0360eb146106b25780636f8b44b0146106c757806370a08231146106e757600080fd5b80633ccfd60b1161027f57806342966c6811610228578063547520fe11610202578063547520fe1461062a57806355f804b31461064a578063582abd121461066a5780636352211e1461069257600080fd5b806342966c68146105cc578063468f87f2146105ec5780634b3197131461061457600080fd5b80634193cdf8116102595780634193cdf81461057757806341f434341461059757806342842e0e146105b957600080fd5b80633ccfd60b146105275780633d43675a1461052f5780634121555e1461054f57600080fd5b806318160ddd116102e15780632478d639116102bb5780632478d639146104cd578063285e61d1146104ed57806332b9de9a1461050d57600080fd5b806318160ddd1461048157806323b872dd1461049a57806323d2bf1e146104ad57600080fd5b8063095ea7b311610312578063095ea7b3146103d557806312b58349146103ea578063140364a11461040757600080fd5b806301ffc9a71461033957806306fdde031461036e578063081812fc14610390575b600080fd5b34801561034557600080fd5b50610359610354366004612d6f565b61099b565b60405190151581526020015b60405180910390f35b34801561037a57600080fd5b50610383610a80565b6040516103659190612e02565b34801561039c57600080fd5b506103b06103ab366004612e15565b610b12565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610365565b6103e86103e3366004612e50565b610b7c565b005b3480156103f657600080fd5b50475b604051908152602001610365565b34801561041357600080fd5b50610427610422366004612e15565b610b95565b6040516103659190815173ffffffffffffffffffffffffffffffffffffffff16815260208083015167ffffffffffffffff169082015260408083015115159082015260609182015162ffffff169181019190915260800190565b34801561048d57600080fd5b50600154600054036103f9565b6103e86104a8366004612e7c565b610bc2565b3480156104b957600080fd5b506103e86104c8366004612ecb565b610bfa565b3480156104d957600080fd5b506103f96104e8366004612ee8565b610c97565b3480156104f957600080fd5b50610359610508366004613019565b610cd2565b34801561051957600080fd5b50600e546103599060ff1681565b6103e8610dd5565b34801561053b57600080fd5b506103e861054a366004612ecb565b610eae565b34801561055b57600080fd5b506103b0737d0b3f2f241caede2d6d885bb6d7f149ecdfba2481565b34801561058357600080fd5b506103e86105923660046130be565b610f4d565b3480156105a357600080fd5b506103b06daaeb6d7670e522a718067333cd4e81565b6103e86105c7366004612e7c565b6111ee565b3480156105d857600080fd5b506103e86105e7366004612e15565b611220565b3480156105f857600080fd5b506103b073f03c4e6b6187aca96b18162cbb4468fc6e33912081565b34801561062057600080fd5b506103f9600b5481565b34801561063657600080fd5b506103e8610645366004612e15565b611287565b34801561065657600080fd5b506103e8610665366004613152565b6112f3565b34801561067657600080fd5b506103b073918de5f6a7411219d7ea785dce2d5d6b120b291281565b34801561069e57600080fd5b506103b06106ad366004612e15565b611371565b3480156106be57600080fd5b5061038361137c565b3480156106d357600080fd5b506103e86106e2366004612e15565b61140a565b3480156106f357600080fd5b506103f9610702366004612ee8565b611476565b34801561071357600080fd5b506103e86114f8565b34801561072857600080fd5b506103f9600d5481565b34801561073e57600080fd5b50600b546103f9565b34801561075357600080fd5b5060085473ffffffffffffffffffffffffffffffffffffffff166103b0565b34801561077e57600080fd5b5061038361156b565b34801561079357600080fd5b506103e86107a2366004612ecb565b61157a565b3480156107b357600080fd5b506103f9611618565b3480156107c857600080fd5b506103e86107d736600461319b565b61162d565b3480156107e857600080fd5b506000546103f9565b3480156107fd57600080fd5b50600e5461035990610100900460ff1681565b6103e861081e3660046131d4565b611641565b34801561082f57600080fd5b5061038361083e366004612e15565b61167b565b34801561084f57600080fd5b506012546103b09073ffffffffffffffffffffffffffffffffffffffff1681565b34801561087c57600080fd5b506103e861088b366004613240565b611754565b34801561089c57600080fd5b506103596108ab366004613290565b611903565b3480156108bc57600080fd5b506103f9600c5481565b3480156108d257600080fd5b506103f96119e7565b3480156108e757600080fd5b506103f96108f6366004612ee8565b6119f2565b34801561090757600080fd5b50610359610916366004613337565b611a2a565b34801561092757600080fd5b506103e8610936366004613365565b611b2b565b34801561094757600080fd5b506103e8610956366004612ee8565b611d22565b34801561096757600080fd5b506103e86109763660046133d1565b611e1b565b34801561098757600080fd5b50600e546103599062010000900460ff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083161480610a2e57507f80ac58cd000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b80610a7a57507f5b5e139f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b606060028054610a8f9061349e565b80601f0160208091040260200160405190810160405280929190818152602001828054610abb9061349e565b8015610b085780601f10610add57610100808354040283529160200191610b08565b820191906000526020600020905b815481529060010190602001808311610aeb57829003601f168201915b5050505050905090565b6000610b1d82611e5d565b610b53576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060009081526006602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b81610b8681611e9d565b610b908383611fa2565b505050565b604080516080810182526000808252602082018190529181018290526060810191909152610a7a8261208d565b8273ffffffffffffffffffffffffffffffffffffffff81163314610be957610be933611e9d565b610bf484848461212b565b50505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314610c665760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b600e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6000610a7a8273ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205460801c67ffffffffffffffff1690565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018290526000908190605401604051602081830303815290604052805190602001209050600081604051602001610d6791907f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b60405160208183030381529060405280519060200120905073918de5f6a7411219d7ea785dce2d5d6b120b291273ffffffffffffffffffffffffffffffffffffffff16610db482876123bd565b73ffffffffffffffffffffffffffffffffffffffff16149695505050505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314610e3c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b6040514790600090339083908381818185875af1925050503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5050905080610e9357600080fd5b81600b6000828254610ea59190613521565b90915550505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314610f155760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600e805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055565b60026009541415610fa05760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c5d565b6002600955600e54610100900460ff1615610ffd5760405162461bcd60e51b815260206004820152601b60248201527f52656465656d696e6720686173206265656e2064697361626c656400000000006044820152606401610c5d565b8382146110725760405162461bcd60e51b815260206004820152602f60248201527f496e76616c6964206361727269657249647320616e642063617449647320286c60448201527f656e677468206d69736d617463682900000000000000000000000000000000006064820152608401610c5d565b611080338287878787611903565b6110cc5760405162461bcd60e51b815260206004820152601160248201527f5369676e617475726520696e76616c69640000000000000000000000000000006044820152606401610c5d565b60005b848110156111e1576110fa8686838181106110ec576110ec613539565b90506020020135600161245a565b73f03c4e6b6187aca96b18162cbb4468fc6e3391206342842e0e737d0b3f2f241caede2d6d885bb6d7f149ecdfba243387878681811061113c5761113c613539565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e088901b16815273ffffffffffffffffffffffffffffffffffffffff958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b1580156111b857600080fd5b505af11580156111cc573d6000803e3d6000fd5b50505050806111da90613568565b90506110cf565b5050600160095550505050565b8273ffffffffffffffffffffffffffffffffffffffff811633146112155761121533611e9d565b610bf4848484612602565b600e5462010000900460ff16156112795760405162461bcd60e51b815260206004820152601360248201527f4275726e696e672069732064697361626c6564000000000000000000000000006044820152606401610c5d565b61128481600161245a565b50565b60085473ffffffffffffffffffffffffffffffffffffffff1633146112ee5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600d55565b60085473ffffffffffffffffffffffffffffffffffffffff16331461135a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b805161136d90600a906020840190612ca8565b5050565b6000610a7a8261261d565b600a80546113899061349e565b80601f01602080910402602001604051908101604052809291908181526020018280546113b59061349e565b80156114025780601f106113d757610100808354040283529160200191611402565b820191906000526020600020905b8154815290600101906020018083116113e557829003601f168201915b505050505081565b60085473ffffffffffffffffffffffffffffffffffffffff1633146114715760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600c55565b600073ffffffffffffffffffffffffffffffffffffffff82166114c5576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205467ffffffffffffffff1690565b60085473ffffffffffffffffffffffffffffffffffffffff16331461155f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b61156960006126ce565b565b606060038054610a8f9061349e565b60085473ffffffffffffffffffffffffffffffffffffffff1633146115e15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b600e8054911515610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909216919091179055565b600047600b546116289190613521565b905090565b8161163781611e9d565b610b908383612745565b8373ffffffffffffffffffffffffffffffffffffffff811633146116685761166833611e9d565b611674858585856127dc565b5050505050565b606061168682611e5d565b6116f85760405162461bcd60e51b815260206004820152602160248201527f4552433732314d657461646174613a204e6f6e6578697374656e7420746f6b6560448201527f6e000000000000000000000000000000000000000000000000000000000000006064820152608401610c5d565b6000611702612846565b90506000815111611722576040518060200160405280600081525061174d565b8061172c84612855565b60405160200161173d9291906135a1565b6040516020818303038152906040525b9392505050565b600260095414156117a75760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610c5d565b6002600955600e5460ff16156117ff5760405162461bcd60e51b815260206004820152601a60248201527f436c61696d696e6720686173206265656e2064697361626c65640000000000006044820152606401610c5d565b61180a338285610cd2565b6118565760405162461bcd60e51b815260206004820152601160248201527f5369676e617475726520696e76616c69640000000000000000000000000000006044820152606401610c5d565b3360009081526005602052604080822054901c67ffffffffffffffff169061187e82866135d0565b9050600d5481111561188f5750600d545b8084111561189b578093505b600054600c546118ab8683613521565b11156118f95760405162461bcd60e51b815260206004820152601260248201527f45786365656473206d617820737570706c7900000000000000000000000000006044820152606401610c5d565b6111e13386612987565b600080858589868660405160200161191f95949392919061362d565b60405160208183030381529060405280519060200120905060008160405160200161197691907f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b60405160208183030381529060405280519060200120905073918de5f6a7411219d7ea785dce2d5d6b120b291273ffffffffffffffffffffffffffffffffffffffff166119c3828a6123bd565b73ffffffffffffffffffffffffffffffffffffffff16149998505050505050505050565b600061162860015490565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600560205260408082205467ffffffffffffffff911c16610a7a565b6012546040517fc455279100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015260009281169190841690829063c455279190602401602060405180830381865afa158015611aa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac6919061367c565b73ffffffffffffffffffffffffffffffffffffffff161415611aec576001915050610a7a565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526007602090815260408083209387168352929052205460ff165b949350505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314611b925760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b828114611c075760405162461bcd60e51b815260206004820152603360248201527f496e76616c6964207175616e74697469657320616e6420726563697069656e7460448201527f7320286c656e677468206d69736d6174636829000000000000000000000000006064820152608401610c5d565b600080611c1360005490565b905060005b85811015611c5657868682818110611c3257611c32613539565b9050602002013583611c449190613521565b9250611c4f81613568565b9050611c18565b50600c54611c648383613521565b1115611cb25760405162461bcd60e51b815260206004820152601260248201527f45786365656473206d6178206d7570706c7900000000000000000000000000006044820152606401610c5d565b6000915060005b83811015611d1957611d09858583818110611cd657611cd6613539565b9050602002016020810190611ceb9190612ee8565b888884818110611cfd57611cfd613539565b90506020020135612987565b611d1281613568565b9050611cb9565b50505050505050565b60085473ffffffffffffffffffffffffffffffffffffffff163314611d895760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c5d565b73ffffffffffffffffffffffffffffffffffffffff8116611e125760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610c5d565b611284816126ce565b60005b8151811015610bf457611e4b8484848481518110611e3e57611e3e613539565b6020026020010151610bc2565b80611e5581613568565b915050611e1e565b6000805482108015610a7a5750506000908152600460205260409020547c0100000000000000000000000000000000000000000000000000000000161590565b6daaeb6d7670e522a718067333cd4e3b15611284576040517fc617113400000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611f30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f549190613699565b611284576040517fede71dcc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610c5d565b6000611fad82611371565b90503373ffffffffffffffffffffffffffffffffffffffff82161461200c57611fd68133611a2a565b61200c576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526006602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b604080516080810182526000808252602082018190529181018290526060810191909152610a7a6120bd8361261d565b6040805160808101825273ffffffffffffffffffffffffffffffffffffffff8316815260a083901c67ffffffffffffffff1660208201527c0100000000000000000000000000000000000000000000000000000000831615159181019190915260e89190911c606082015290565b60006121368261261d565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461219d576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260066020526040902080546121d68187335b73ffffffffffffffffffffffffffffffffffffffff9081169116811491141790565b61221a576121e48633611a2a565b61221a576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516612267576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b801561227257600082555b73ffffffffffffffffffffffffffffffffffffffff86811660009081526005602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019055918716808252919020805460010190554260a01b177c0200000000000000000000000000000000000000000000000000000000176000858152600460205260409020557c0200000000000000000000000000000000000000000000000000000000831661235a57600184016000818152600460205260409020546123585760005481146123585760008181526004602052604090208490555b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b6000806000806123cc85612abe565b6040805160008152602081018083528b905260ff8316918101919091526060810184905260808101839052929550909350915060019060a0016020604051602081039080840390855afa158015612427573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00151979650505050505050565b60006124658361261d565b90508060008061248386600090815260066020526040902080549091565b9150915084156124dc576124988184336121b4565b6124dc576124a68333611a2a565b6124dc576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80156124e757600082555b73ffffffffffffffffffffffffffffffffffffffff8316600081815260056020526040902080546fffffffffffffffffffffffffffffffff0190554260a01b177c0300000000000000000000000000000000000000000000000000000000176000878152600460205260409020557c020000000000000000000000000000000000000000000000000000000084166125ad57600186016000818152600460205260409020546125ab5760005481146125ab5760008181526004602052604090208590555b505b604051869060009073ffffffffffffffffffffffffffffffffffffffff8616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050600180548101905550505050565b610b9083838360405180602001604052806000815250611641565b60008160005481101561269c576000818152600460205260409020547c0100000000000000000000000000000000000000000000000000000000811661269a575b8061174d57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0160008181526004602052604090205461265e565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b33600081815260076020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6127e7848484610bc2565b73ffffffffffffffffffffffffffffffffffffffff83163b15610bf45761281084848484612b32565b610bf4576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6060600a8054610a8f9061349e565b60608161289557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156128bf57806128a981613568565b91506128b89050600a836136e5565b9150612899565b60008167ffffffffffffffff8111156128da576128da612f05565b6040519080825280601f01601f191660200182016040528015612904576020820181803683370190505b5090505b8415611b23576129196001836135d0565b9150612926600a866136f9565b612931906030613521565b60f81b81838151811061294657612946613539565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612980600a866136e5565b9450612908565b600054816129c1576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114612a7d57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101612a45565b5081612ab5576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005550505050565b60008060008351604114612b145760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207369676e6174757265206c656e67746800000000000000006044820152606401610c5d565b50505060208101516040820151606090920151909260009190911a90565b6040517f150b7a0200000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290612b8d90339089908890889060040161370d565b6020604051808303816000875af1925050508015612be6575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612be391810190613756565b60015b612c5a573d808015612c14576040519150601f19603f3d011682016040523d82523d6000602084013e612c19565b606091505b508051612c52576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050949350505050565b828054612cb49061349e565b90600052602060002090601f016020900481019282612cd65760008555612d1c565b82601f10612cef57805160ff1916838001178555612d1c565b82800160010185558215612d1c579182015b82811115612d1c578251825591602001919060010190612d01565b50612d28929150612d2c565b5090565b5b80821115612d285760008155600101612d2d565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461128457600080fd5b600060208284031215612d8157600080fd5b813561174d81612d41565b60005b83811015612da7578181015183820152602001612d8f565b83811115610bf45750506000910152565b60008151808452612dd0816020860160208601612d8c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061174d6020830184612db8565b600060208284031215612e2757600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461128457600080fd5b60008060408385031215612e6357600080fd5b8235612e6e81612e2e565b946020939093013593505050565b600080600060608486031215612e9157600080fd5b8335612e9c81612e2e565b92506020840135612eac81612e2e565b929592945050506040919091013590565b801515811461128457600080fd5b600060208284031215612edd57600080fd5b813561174d81612ebd565b600060208284031215612efa57600080fd5b813561174d81612e2e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612f7b57612f7b612f05565b604052919050565b600067ffffffffffffffff831115612f9d57612f9d612f05565b612fce60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601612f34565b9050828152838383011115612fe257600080fd5b828260208301376000602084830101529392505050565b600082601f83011261300a57600080fd5b61174d83833560208501612f83565b60008060006060848603121561302e57600080fd5b833561303981612e2e565b9250602084013567ffffffffffffffff81111561305557600080fd5b61306186828701612ff9565b925050604084013590509250925092565b60008083601f84011261308457600080fd5b50813567ffffffffffffffff81111561309c57600080fd5b6020830191508360208260051b85010111156130b757600080fd5b9250929050565b6000806000806000606086880312156130d657600080fd5b853567ffffffffffffffff808211156130ee57600080fd5b6130fa89838a01613072565b9097509550602088013591508082111561311357600080fd5b61311f89838a01613072565b9095509350604088013591508082111561313857600080fd5b5061314588828901612ff9565b9150509295509295909350565b60006020828403121561316457600080fd5b813567ffffffffffffffff81111561317b57600080fd5b8201601f8101841361318c57600080fd5b611b2384823560208401612f83565b600080604083850312156131ae57600080fd5b82356131b981612e2e565b915060208301356131c981612ebd565b809150509250929050565b600080600080608085870312156131ea57600080fd5b84356131f581612e2e565b9350602085013561320581612e2e565b925060408501359150606085013567ffffffffffffffff81111561322857600080fd5b61323487828801612ff9565b91505092959194509250565b60008060006060848603121561325557600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561327a57600080fd5b61328686828701612ff9565b9150509250925092565b600080600080600080608087890312156132a957600080fd5b86356132b481612e2e565b9550602087013567ffffffffffffffff808211156132d157600080fd5b6132dd8a838b01612ff9565b965060408901359150808211156132f357600080fd5b6132ff8a838b01613072565b9096509450606089013591508082111561331857600080fd5b5061332589828a01613072565b979a9699509497509295939492505050565b6000806040838503121561334a57600080fd5b823561335581612e2e565b915060208301356131c981612e2e565b6000806000806040858703121561337b57600080fd5b843567ffffffffffffffff8082111561339357600080fd5b61339f88838901613072565b909650945060208701359150808211156133b857600080fd5b506133c587828801613072565b95989497509550505050565b6000806000606084860312156133e657600080fd5b83356133f181612e2e565b925060208481013561340281612e2e565b9250604085013567ffffffffffffffff8082111561341f57600080fd5b818701915087601f83011261343357600080fd5b81358181111561344557613445612f05565b8060051b9150613456848301612f34565b818152918301840191848101908a84111561347057600080fd5b938501935b8385101561348e57843582529385019390850190613475565b8096505050505050509250925092565b600181811c908216806134b257607f821691505b602082108114156134ec577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115613534576135346134f2565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561359a5761359a6134f2565b5060010190565b600083516135b3818460208801612d8c565b8351908301906135c7818360208801612d8c565b01949350505050565b6000828210156135e2576135e26134f2565b500390565b60007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561361657600080fd5b8260051b8083863760009401938452509192915050565b600061363a8287896135e7565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008660601b1681526136706014820185876135e7565b98975050505050505050565b60006020828403121561368e57600080fd5b815161174d81612e2e565b6000602082840312156136ab57600080fd5b815161174d81612ebd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826136f4576136f46136b6565b500490565b600082613708576137086136b6565b500690565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261374c6080830184612db8565b9695505050505050565b60006020828403121561376857600080fd5b815161174d81612d4156fea2646970667358221220d41385961fb5df226d9a25f31d9e1621938c51c5053299c875de1ed2f946764764736f6c634300080a0033

Deployed Bytecode Sourcemap

546:9627:16:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9410:639:4;;;;;;;;;;-1:-1:-1;9410:639:4;;;;;:::i;:::-;;:::i;:::-;;;611:14:21;;604:22;586:41;;574:2;559:18;9410:639:4;;;;;;;;10312:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;16803:218::-;;;;;;;;;;-1:-1:-1;16803:218:4;;;;;:::i;:::-;;:::i;:::-;;;1809:42:21;1797:55;;;1779:74;;1767:2;1752:18;16803:218:4;1633:226:21;1808:165:16;;;;;;:::i;:::-;;:::i;:::-;;9071:104;;;;;;;;;;-1:-1:-1;9146:21:16;9071:104;;;2489:25:21;;;2477:2;2462:18;9071:104:16;2343:177:21;8793:163:16;;;;;;;;;;-1:-1:-1;8793:163:16;;;;;:::i;:::-;;:::i;:::-;;;;;;2758:13:21;;2773:42;2754:62;2736:81;;2877:4;2865:17;;;2859:24;2885:18;2855:49;2833:20;;;2826:79;2975:4;2963:17;;;2957:24;2950:32;2943:40;2921:20;;;2914:70;3044:4;3032:17;;;3026:24;3052:8;3022:39;3000:20;;;2993:69;;;;2723:3;2708:19;;2525:543;6063:323:4;;;;;;;;;;-1:-1:-1;6337:12:4;;6124:7;6321:13;:28;6063:323;;1981:171:16;;;;;;:::i;:::-;;:::i;7950:125::-;;;;;;;;;;-1:-1:-1;7950:125:16;;;;;:::i;:::-;;:::i;8672:113::-;;;;;;;;;;-1:-1:-1;8672:113:16;;;;;:::i;:::-;;:::i;3233:404::-;;;;;;;;;;-1:-1:-1;3233:404:16;;;;;:::i;:::-;;:::i;841:36::-;;;;;;;;;;-1:-1:-1;841:36:16;;;;;;;;9394:273;;;:::i;8220:121::-;;;;;;;;;;-1:-1:-1;8220:121:16;;;;;:::i;:::-;;:::i;1065:85::-;;;;;;;;;;;;1108:42;1065:85;;4169:764;;;;;;;;;;-1:-1:-1;4169:764:16;;;;;:::i;:::-;;:::i;752:143:17:-;;;;;;;;;;;;852:42;752:143;;2160:179:16;;;;;;:::i;:::-;;:::i;6772:153::-;;;;;;;;;;-1:-1:-1;6772:153:16;;;;;:::i;:::-;;:::i;970:88::-;;;;;;;;;;;;1016:42;970:88;;706:33;;;;;;;;;;;;;;;;7624:92;;;;;;;;;;-1:-1:-1;7624:92:16;;;;;:::i;:::-;;:::i;7838:104::-;;;;;;;;;;-1:-1:-1;7838:104:16;;;;;:::i;:::-;;:::i;1157:75::-;;;;;;;;;;;;1190:42;1157:75;;11705:152:4;;;;;;;;;;-1:-1:-1;11705:152:4;;;;;:::i;:::-;;:::i;678:21:16:-;;;;;;;;;;;;;:::i;7724:106::-;;;;;;;;;;-1:-1:-1;7724:106:16;;;;;:::i;:::-;;:::i;7247:233:4:-;;;;;;;;;;-1:-1:-1;7247:233:4;;;;;:::i;:::-;;:::i;1661:101:18:-;;;;;;;;;;;;;:::i;784:27:16:-;;;;;;;;;;;;;;;;8964:99;;;;;;;;;;-1:-1:-1;9041:14:16;;8964:99;;1029:85:18;;;;;;;;;;-1:-1:-1;1101:6:18;;;;1029:85;;10488:104:4;;;;;;;;;;;;;:::i;8083:129:16:-;;;;;;;;;;-1:-1:-1;8083:129:16;;;;;:::i;:::-;;:::i;9183:121::-;;;;;;;;;;;;;:::i;1624:176::-;;;;;;;;;;-1:-1:-1;1624:176:16;;;;;:::i;:::-;;:::i;8349:93::-;;;;;;;;;;-1:-1:-1;8393:7:16;6730:13:4;8349:93:16;9183:121;884:36;;;;;;;;;;-1:-1:-1;884:36:16;;;;;;;;;;;2347:245;;;;;;:::i;:::-;;:::i;7277:339::-;;;;;;;;;;-1:-1:-1;7277:339:16;;;;;:::i;:::-;;:::i;1400:80::-;;;;;;;;;;-1:-1:-1;1400:80:16;;;;;;;;4995:1040;;;;;;;;;;-1:-1:-1;4995:1040:16;;;;;:::i;:::-;;:::i;3645:439::-;;;;;;;;;;-1:-1:-1;3645:439:16;;;;;:::i;:::-;;:::i;746:31::-;;;;;;;;;;;;;;;;8571:93;;;;;;;;;;;;;:::i;8450:113::-;;;;;;;;;;-1:-1:-1;8450:113:16;;;;;:::i;:::-;;:::i;9768:402::-;;;;;;;;;;-1:-1:-1;9768:402:16;;;;;:::i;:::-;;:::i;6065:699::-;;;;;;;;;;-1:-1:-1;6065:699:16;;;;;:::i;:::-;;:::i;1911:198:18:-;;;;;;;;;;-1:-1:-1;1911:198:18;;;;;:::i;:::-;;:::i;6933:220:16:-;;;;;;;;;;-1:-1:-1;6933:220:16;;;;;:::i;:::-;;:::i;927:34::-;;;;;;;;;;-1:-1:-1;927:34:16;;;;;;;;;;;9410:639:4;9495:4;9819:25;;;;;;:102;;-1:-1:-1;9896:25:4;;;;;9819:102;:179;;;-1:-1:-1;9973:25:4;;;;;9819:179;9799:199;9410:639;-1:-1:-1;;9410:639:4:o;10312:100::-;10366:13;10399:5;10392:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10312:100;:::o;16803:218::-;16879:7;16904:16;16912:7;16904;:16::i;:::-;16899:64;;16929:34;;;;;;;;;;;;;;16899:64;-1:-1:-1;16983:24:4;;;;:15;:24;;;;;:30;;;;16803:218::o;1808:165:16:-;1912:8;2273:30:17;2294:8;2273:20;:30::i;:::-;1933:32:16::1;1947:8;1957:7;1933:13;:32::i;:::-;1808:165:::0;;;:::o;8793:163::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8927:21:16;8940:7;8927:12;:21::i;1981:171::-;2090:4;2093:18:17;;;2101:10;2093:18;2089:83;;2128:32;2149:10;2128:20;:32::i;:::-;2107:37:16::1;2126:4;2132:2;2136:7;2107:18;:37::i;:::-;1981:171:::0;;;;:::o;7950:125::-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;;;;;;;;;8031:16:16::1;:36:::0;;;::::1;::::0;::::1;;::::0;;;::::1;::::0;;7950:125::o;8672:113::-;8730:7;8757:20;8771:5;7927:25:4;;7899:7;7927:25;;;:18;:25;;;;;;1671:3;7927:50;1406:13;7926:82;;7838:178;3233:404:16;3396:40;;13993:66:21;13980:2;13976:15;;;13972:88;3396:40:16;;;13960:101:21;14077:12;;;14070:28;;;3347:4:16;;;;14114:12:21;;3396:40:16;;;;;;;;;;;;3386:51;;;;;;3364:73;;3448:28;3542:11;3489:65;;;;;;;14379:66:21;14367:79;;14471:2;14462:12;;14455:28;;;;14508:2;14499:12;;14137:380;3489:65:16;;;;;;;;;;;;;3479:76;;;;;;3448:107;;1190:42;3573:56;;:46;3587:20;3609:9;3573:13;:46::i;:::-;:56;;;;3233:404;-1:-1:-1;;;;;;3233:404:16:o;9394:273::-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;9515:64:16::1;::::0;9464:21:::1;::::0;9450:11:::1;::::0;9523:10:::1;::::0;9464:21;;9450:11;9515:64;9450:11;9515:64;9464:21;9523:10;9515:64:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9496:83;;;9598:7;9590:16;;;::::0;::::1;;9635:3;9617:14;;:21;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;;9394:273:16:o;8220:121::-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;8299:15:16::1;:34:::0;;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;8220:121::o;4169:764::-;1744:1:19;2325:7;;:19;;2317:63;;;;-1:-1:-1;;;2317:63:19;;15256:2:21;2317:63:19;;;15238:21:21;15295:2;15275:18;;;15268:30;15334:33;15314:18;;;15307:61;15385:18;;2317:63:19;15054:355:21;2317:63:19;1744:1;2455:7;:18;4316:17:16::1;::::0;::::1;::::0;::::1;;;4315:18;4307:58;;;::::0;-1:-1:-1;;;4307:58:16;;15616:2:21;4307:58:16::1;::::0;::::1;15598:21:21::0;15655:2;15635:18;;;15628:30;15694:29;15674:18;;;15667:57;15741:18;;4307:58:16::1;15414:351:21::0;4307:58:16::1;4384:34:::0;;::::1;4376:94;;;::::0;-1:-1:-1;;;4376:94:16;;15972:2:21;4376:94:16::1;::::0;::::1;15954:21:21::0;16011:2;15991:18;;;15984:30;16050:34;16030:18;;;16023:62;16121:17;16101:18;;;16094:45;16156:19;;4376:94:16::1;15770:411:21::0;4376:94:16::1;4489:63;4510:10;4522:9;4533:10;;4545:6;;4489:20;:63::i;:::-;4481:93;;;::::0;-1:-1:-1;;;4481:93:16;;16388:2:21;4481:93:16::1;::::0;::::1;16370:21:21::0;16427:2;16407:18;;;16400:30;16466:19;16446:18;;;16439:47;16503:18;;4481:93:16::1;16186:341:21::0;4481:93:16::1;4623:9;4619:307;4638:21:::0;;::::1;4619:307;;;4681:26;4687:10;;4698:1;4687:13;;;;;;;:::i;:::-;;;;;;;4702:4;4681:5;:26::i;:::-;1016:42;4780:46;1108:42;4845:10;4857:6:::0;;4864:1;4857:9;;::::1;;;;;:::i;:::-;4780:87;::::0;;::::1;::::0;;;;;;16933:42:21;17002:15;;;4780:87:16::1;::::0;::::1;16984:34:21::0;17054:15;;;;17034:18;;;17027:43;-1:-1:-1;4857:9:16::1;::::0;;::::1;;;17086:18:21::0;;;17079:34;16896:18;;4780:87:16::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;4661:3;;;;:::i;:::-;;;4619:307;;;-1:-1:-1::0;;1701:1:19;2628:7;:22;-1:-1:-1;;;;4169:764:16:o;2160:179::-;2273:4;2093:18:17;;;2101:10;2093:18;2089:83;;2128:32;2149:10;2128:20;:32::i;:::-;2290:41:16::1;2313:4;2319:2;2323:7;2290:22;:41::i;6772:153::-:0;6847:15;;;;;;;6846:16;6838:48;;;;-1:-1:-1;;;6838:48:16;;17526:2:21;6838:48:16;;;17508:21:21;17565:2;17545:18;;;17538:30;17604:21;17584:18;;;17577:49;17643:18;;6838:48:16;17324:343:21;6838:48:16;6897:20;6903:7;6912:4;6897:5;:20::i;:::-;6772:153;:::o;7624:92::-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;7690:7:16::1;:18:::0;7624:92::o;7838:104::-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;7913:21:16;;::::1;::::0;:7:::1;::::0;:21:::1;::::0;::::1;::::0;::::1;:::i;:::-;;7838:104:::0;:::o;11705:152:4:-;11777:7;11820:27;11839:7;11820:18;:27::i;678:21:16:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7724:106::-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;7797:9:16::1;:25:::0;7724:106::o;7247:233:4:-;7319:7;7343:19;;;7339:60;;7371:28;;;;;;;;;;;;;;7339:60;-1:-1:-1;7417:25:4;;;;;;:18;:25;;;;;;1406:13;7417:55;;7247:233::o;1661:101:18:-;1101:6;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;1725:30:::1;1752:1;1725:18;:30::i;:::-;1661:101::o:0;10488:104:4:-;10544:13;10577:7;10570:14;;;;;:::i;8083:129:16:-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;8166:17:16::1;:38:::0;;;::::1;;;;::::0;;;::::1;::::0;;;::::1;::::0;;8083:129::o;9183:121::-;9230:7;9146:21;9041:14;;9257:39;;;;:::i;:::-;9250:46;;9183:121;:::o;1624:176::-;1728:8;2273:30:17;2294:8;2273:20;:30::i;:::-;1749:43:16::1;1773:8;1783;1749:23;:43::i;2347:245::-:0;2515:4;2093:18:17;;;2101:10;2093:18;2089:83;;2128:32;2149:10;2128:20;:32::i;:::-;2537:47:16::1;2560:4;2566:2;2570:7;2579:4;2537:22;:47::i;:::-;2347:245:::0;;;;;:::o;7277:339::-;7350:13;7384:16;7392:7;7384;:16::i;:::-;7376:62;;;;-1:-1:-1;;;7376:62:16;;17874:2:21;7376:62:16;;;17856:21:21;17913:2;17893:18;;;17886:30;17952:34;17932:18;;;17925:62;18023:3;18003:18;;;17996:31;18044:19;;7376:62:16;17672:397:21;7376:62:16;7449:28;7480:10;:8;:10::i;:::-;7449:41;;7539:1;7514:14;7508:28;:32;:100;;;;;;;;;;;;;;;;;7567:14;7583:18;:7;:16;:18::i;:::-;7550:52;;;;;;;;;:::i;:::-;;;;;;;;;;;;;7508:100;7501:107;7277:339;-1:-1:-1;;;7277:339:16:o;4995:1040::-;1744:1:19;2325:7;;:19;;2317:63;;;;-1:-1:-1;;;2317:63:19;;15256:2:21;2317:63:19;;;15238:21:21;15295:2;15275:18;;;15268:30;15334:33;15314:18;;;15307:61;15385:18;;2317:63:19;15054:355:21;2317:63:19;1744:1;2455:7;:18;5127:16:16::1;::::0;::::1;;5126:17;5118:56;;;::::0;-1:-1:-1;;;5118:56:16;;18751:2:21;5118:56:16::1;::::0;::::1;18733:21:21::0;18790:2;18770:18;;;18763:30;18829:28;18809:18;;;18802:56;18875:18;;5118:56:16::1;18549:350:21::0;5118:56:16::1;5193:60;5213:10;5225:9;5236:16;5193:19;:60::i;:::-;5185:90;;;::::0;-1:-1:-1;;;5185:90:16;;16388:2:21;5185:90:16::1;::::0;::::1;16370:21:21::0;16427:2;16407:18;;;16400:30;16466:19;16446:18;;;16439:47;16503:18;;5185:90:16::1;16186:341:21::0;5185:90:16::1;5349:10;5314:18;7651:25:4::0;;;:18;:25;;1544:2;7651:25;;;;:50;;1406:13;7650:82;;5416:29:16::1;7650:82:4::0;5416:16:16;:29:::1;:::i;:::-;5394:51;;5583:7;;5569:11;:21;5566:74;;;-1:-1:-1::0;5621:7:16::1;::::0;5566:74:::1;5706:11;5695:8;:22;5692:76;;;5745:11;5734:22;;5692:76;5778:14;6730:13:4::0;5876:9:16::1;::::0;5854:17:::1;5863:8:::0;6730:13:4;5854:17:16::1;:::i;:::-;5853:32;;5845:63;;;::::0;-1:-1:-1;;;5845:63:16;;19236:2:21;5845:63:16::1;::::0;::::1;19218:21:21::0;19275:2;19255:18;;;19248:30;19314:20;19294:18;;;19287:48;19352:18;;5845:63:16::1;19034:342:21::0;5845:63:16::1;5919:27;5925:10;5937:8;5919:5;:27::i;3645:439::-:0;3792:4;3809:19;3858:10;;3870:4;3876:6;;3841:42;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3831:53;;;;;;3809:75;;3895:28;3989:11;3936:65;;;;;;;14379:66:21;14367:79;;14471:2;14462:12;;14455:28;;;;14508:2;14499:12;;14137:380;3936:65:16;;;;;;;;;;;;;3926:76;;;;;;3895:107;;1190:42;4020:56;;:46;4034:20;4056:9;4020:13;:46::i;:::-;:56;;;;3645:439;-1:-1:-1;;;;;;;;;3645:439:16:o;8571:93::-;8615:7;8642:14;6944:12:4;;;6862:102;8450:113:16;7651:25:4;;;8508:7:16;7651:25:4;;;:18;:25;;1544:2;7651:25;;;;1406:13;7651:50;;7650:82;8535:20:16;7562:178:4;9768:402:16;9981:20;;10025:28;;;;;9981:20;1797:55:21;;;10025:28:16;;;1779:74:21;9857:4:16;;9981:20;;;10017:49;;;;9981:20;;10025:21;;1752:18:21;;10025:28:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10017:49;;;10013:93;;;10090:4;10083:11;;;;;10013:93;17873:25:4;;;;17849:4;17873:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;10123:39:16;10116:46;9768:402;-1:-1:-1;;;;9768:402:16:o;6065:699::-;1101:6:18;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;6192:38:16;;::::1;6184:102;;;::::0;-1:-1:-1;;;6184:102:16;;20808:2:21;6184:102:16::1;::::0;::::1;20790:21:21::0;20847:2;20827:18;;;20820:30;20886:34;20866:18;;;20859:62;20957:21;20937:18;;;20930:49;20996:19;;6184:102:16::1;20606:415:21::0;6184:102:16::1;6297:21;6333:14:::0;6350::::1;6539:7:4::0;6730:13;;6484:296;6350:14:16::1;6333:31;;6405:9;6400:105;6420:21:::0;;::::1;6400:105;;;6480:10;;6491:1;6480:13;;;;;;;:::i;:::-;;;;;;;6463:30;;;;;:::i;:::-;::::0;-1:-1:-1;6443:3:16::1;::::0;::::1;:::i;:::-;;;6400:105;;;-1:-1:-1::0;6549:9:16::1;::::0;6523:22:::1;6532:13:::0;6523:6;:22:::1;:::i;:::-;:35;;6515:66;;;::::0;-1:-1:-1;;;6515:66:16;;21228:2:21;6515:66:16::1;::::0;::::1;21210:21:21::0;21267:2;21247:18;;;21240:30;21306:20;21286:18;;;21279:48;21344:18;;6515:66:16::1;21026:342:21::0;6515:66:16::1;6592:20;;;6628:9;6623:110;6643:21:::0;;::::1;6623:110;;;6686:35;6692:10;;6703:1;6692:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;6707:10;;6718:1;6707:13;;;;;;;:::i;:::-;;;;;;;6686:5;:35::i;:::-;6666:3;::::0;::::1;:::i;:::-;;;6623:110;;;-1:-1:-1::0;;;;;;;6065:699:16:o;1911:198:18:-;1101:6;;1241:23;1101:6;719:10:1;1241:23:18;1233:68;;;;-1:-1:-1;;;1233:68:18;;13644:2:21;1233:68:18;;;13626:21:21;;;13663:18;;;13656:30;13722:34;13702:18;;;13695:62;13774:18;;1233:68:18;13442:356:21;1233:68:18;1999:22:::1;::::0;::::1;1991:73;;;::::0;-1:-1:-1;;;1991:73:18;;21575:2:21;1991:73:18::1;::::0;::::1;21557:21:21::0;21614:2;21594:18;;;21587:30;21653:34;21633:18;;;21626:62;21724:8;21704:18;;;21697:36;21750:19;;1991:73:18::1;21373:402:21::0;1991:73:18::1;2074:28;2093:8;2074:18;:28::i;6933:220:16:-:0;7039:9;7034:112;7058:9;:16;7054:1;:20;7034:112;;;7096:38;7109:5;7116:3;7121:9;7131:1;7121:12;;;;;;;;:::i;:::-;;;;;;;7096;:38::i;:::-;7076:3;;;;:::i;:::-;;;;7034:112;;18174:282:4;18239:4;18329:13;;18319:7;:23;18276:153;;;;-1:-1:-1;;18380:26:4;;;;:17;:26;;;;;;2182:8;18380:44;:49;;18174:282::o;2331:419:17:-;852:42;2522:45;:49;2518:225;;2593:67;;;;;2644:4;2593:67;;;22015:34:21;21964:42;22085:15;;22065:18;;;22058:43;852:42:17;;2593;;21927:18:21;;2593:67:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2588:144;;2688:28;;;;;1809:42:21;1797:55;;2688:28:17;;;1779:74:21;1752:18;;2688:28:17;1633:226:21;16236:408:4;16325:13;16341:16;16349:7;16341;:16::i;:::-;16325:32;-1:-1:-1;719:10:1;16374:28:4;;;;16370:175;;16422:44;16439:5;719:10:1;9768:402:16;:::i;16422:44:4:-;16417:128;;16494:35;;;;;;;;;;;;;;16417:128;16557:24;;;;:15;:24;;;;;;:35;;;;;;;;;;;;;;16608:28;;16557:24;;16608:28;;;;;;;16314:330;16236:408;;:::o;12046:166::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12157:47:4;12176:27;12195:7;12176:18;:27::i;:::-;-1:-1:-1;;;;;;;;14344:41:4;;;;;2065:3;14430:33;;;14396:68;;-1:-1:-1;;;14396:68:4;2182:8;14494:24;;:29;;-1:-1:-1;;;14475:48:4;;;;2586:3;14563:28;;;;-1:-1:-1;;;14534:58:4;-1:-1:-1;14234:366:4;20442:2825;20584:27;20614;20633:7;20614:18;:27::i;:::-;20584:57;;20699:4;20658:45;;20674:19;20658:45;;;20654:86;;20712:28;;;;;;;;;;;;;;20654:86;20754:27;19550:24;;;:15;:24;;;;;19778:26;;20945:68;19778:26;20987:4;719:10:1;20993:19:4;18879:16;19024:32;;;18868:28;;19153:20;;19175:30;;19150:56;;18565:659;20945:68;20940:180;;21033:43;21050:4;719:10:1;9768:402:16;:::i;21033:43:4:-;21028:92;;21085:35;;;;;;;;;;;;;;21028:92;21137:16;;;21133:52;;21162:23;;;;;;;;;;;;;;21133:52;21334:15;21331:160;;;21474:1;21453:19;21446:30;21331:160;21871:24;;;;;;;;:18;:24;;;;;;21869:26;;;;;;21940:22;;;;;;;;;21938:24;;-1:-1:-1;21938:24:4;;;15094:11;15069:23;15065:41;15052:63;2462:8;15052:63;22233:26;;;;:17;:26;;;;;:175;2462:8;22528:47;;22524:627;;22633:1;22623:11;;22601:19;22756:30;;;:17;:30;;;;;;22752:384;;22894:13;;22879:11;:28;22875:242;;23041:30;;;;:17;:30;;;;;:52;;;22875:242;22582:569;22524:627;23198:7;23194:2;23179:27;;23188:4;23179:27;;;;;;;;;;;;20573:2694;;;20442:2825;;;:::o;2644:248:16:-;2745:7;2766:9;2777;2788:7;2799:26;2814:10;2799:14;:26::i;:::-;2843:41;;;;;;;;;;;;22589:25:21;;;22662:4;22650:17;;22630:18;;;22623:45;;;;22684:18;;;22677:34;;;22727:18;;;22720:34;;;2765:60:16;;-1:-1:-1;2765:60:16;;-1:-1:-1;2765:60:16;-1:-1:-1;2843:41:16;;22561:19:21;;2843:41:16;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2843:41:16;;;;;;2644:248;-1:-1:-1;;;;;;;2644:248:16:o;35011:3081:4:-;35091:27;35121;35140:7;35121:18;:27::i;:::-;35091:57;-1:-1:-1;35091:57:4;35161:12;;35283:35;35310:7;19439:27;19550:24;;;:15;:24;;;;;19778:26;;19550:24;;19337:485;35283:35;35226:92;;;;35335:13;35331:316;;;35456:68;35481:15;35498:4;719:10:1;35504:19:4;640:96:1;35456:68:4;35451:184;;35548:43;35565:4;719:10:1;9768:402:16;:::i;35548:43:4:-;35543:92;;35600:35;;;;;;;;;;;;;;35543:92;35803:15;35800:160;;;35943:1;35922:19;35915:30;35800:160;36562:24;;;;;;;:18;:24;;;;;:60;;36590:32;36562:60;;;15094:11;15069:23;15065:41;15052:63;36950:43;15052:63;36860:26;;;;:17;:26;;;;;:205;2462:8;37185:47;;37181:627;;37290:1;37280:11;;37258:19;37413:30;;;:17;:30;;;;;;37409:384;;37551:13;;37536:11;:28;37532:242;;37698:30;;;;:17;:30;;;;;:52;;;37532:242;37239:569;37181:627;37836:35;;37863:7;;37859:1;;37836:35;;;;;;37859:1;;37836:35;-1:-1:-1;;38059:12:4;:14;;;;;;-1:-1:-1;;;;35011:3081:4:o;23363:193::-;23509:39;23526:4;23532:2;23536:7;23509:39;;;;;;;;;;;;:16;:39::i;12860:1275::-;12927:7;12962;13064:13;;13057:4;:20;13053:1015;;;13102:14;13119:23;;;:17;:23;;;;;;2182:8;13208:24;;13204:845;;13873:113;13880:11;13873:113;;-1:-1:-1;13951:6:4;;13933:25;;;;:17;:25;;;;;;13873:113;;13204:845;13079:989;13053:1015;14096:31;;;;;;;;;;;;;;2263:187:18;2355:6;;;;2371:17;;;;;;;;;;;2403:40;;2355:6;;;2371:17;2355:6;;2403:40;;2336:16;;2403:40;2326:124;2263:187;:::o;17361:234:4:-;719:10:1;17456:39:4;;;;:18;:39;;;;;;;;;:49;;;;;;;;;;;;:60;;;;;;;;;;;;;17532:55;;586:41:21;;;17456:49:4;;719:10:1;17532:55:4;;559:18:21;17532:55:4;;;;;;;17361:234;;:::o;24154:407::-;24329:31;24342:4;24348:2;24352:7;24329:12;:31::i;:::-;24375:14;;;;:19;24371:183;;24414:56;24445:4;24451:2;24455:7;24464:5;24414:30;:56::i;:::-;24409:145;;24498:40;;;;;;;;;;;;;;7161:108:16;7221:13;7254:7;7247:14;;;;;:::i;328:703:20:-;384:13;601:10;597:51;;-1:-1:-1;;627:10:20;;;;;;;;;;;;;;;;;;328:703::o;597:51::-;672:5;657:12;711:75;718:9;;711:75;;743:8;;;;:::i;:::-;;-1:-1:-1;765:10:20;;-1:-1:-1;773:2:20;765:10;;:::i;:::-;;;711:75;;;795:19;827:6;817:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;817:17:20;;795:39;;844:150;851:10;;844:150;;877:11;887:1;877:11;;:::i;:::-;;-1:-1:-1;945:10:20;953:2;945:5;:10;:::i;:::-;932:24;;:2;:24;:::i;:::-;919:39;;902:6;909;902:14;;;;;;;;:::i;:::-;;;;:56;;;;;;;;;;-1:-1:-1;972:11:20;981:2;972:11;;:::i;:::-;;;844:150;;27823:2966:4;27896:20;27919:13;27947;27943:44;;27969:18;;;;;;;;;;;;;;27943:44;28475:22;;;;;;;:18;:22;;;;1544:2;28475:22;;;:71;;28513:32;28501:45;;28475:71;;;28789:31;;;:17;:31;;;;;-1:-1:-1;15525:15:4;;15499:24;15495:46;15094:11;15069:23;15065:41;15062:52;15052:63;;28789:173;;29024:23;;;;28789:31;;28475:22;;29789:25;28475:22;;29642:335;30303:1;30289:12;30285:20;30243:346;30344:3;30335:7;30332:16;30243:346;;30562:7;30552:8;30549:1;30522:25;30519:1;30516;30511:59;30397:1;30384:15;30243:346;;;-1:-1:-1;30622:13:4;30618:45;;30644:19;;;;;;;;;;;;;;30618:45;30680:13;:19;-1:-1:-1;1808:165:16;;;:::o;2904:321::-;2968:9;2979;2990:7;3018:3;:10;3032:2;3018:16;3010:53;;;;-1:-1:-1;;;3010:53:16;;23398:2:21;3010:53:16;;;23380:21:21;23437:2;23417:18;;;23410:30;23476:26;23456:18;;;23449:54;23520:18;;3010:53:16;23196:348:21;3010:53:16;-1:-1:-1;;;3118:2:16;3109:12;;3103:19;3156:2;3147:12;;3141:19;3202:2;3193:12;;;3187:19;3103;;3184:1;3179:28;;;;;2904:321::o;26645:716:4:-;26829:88;;;;;26808:4;;26829:45;;;;;;:88;;719:10:1;;26896:4:4;;26902:7;;26911:5;;26829:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26829:88:4;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;26825:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27112:13:4;;27108:235;;27158:40;;;;;;;;;;;;;;27108:235;27301:6;27295:13;27286:6;27282:2;27278:15;27271:38;26825:529;26988:64;;26998:54;26988:64;;-1:-1:-1;26645:716:4;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:177:21;99:66;92:5;88:78;81:5;78:89;68:117;;181:1;178;171:12;196:245;254:6;307:2;295:9;286:7;282:23;278:32;275:52;;;323:1;320;313:12;275:52;362:9;349:23;381:30;405:5;381:30;:::i;638:258::-;710:1;720:113;734:6;731:1;728:13;720:113;;;810:11;;;804:18;791:11;;;784:39;756:2;749:10;720:113;;;851:6;848:1;845:13;842:48;;;-1:-1:-1;;886:1:21;868:16;;861:27;638:258::o;901:317::-;943:3;981:5;975:12;1008:6;1003:3;996:19;1024:63;1080:6;1073:4;1068:3;1064:14;1057:4;1050:5;1046:16;1024:63;:::i;:::-;1132:2;1120:15;1137:66;1116:88;1107:98;;;;1207:4;1103:109;;901:317;-1:-1:-1;;901:317:21:o;1223:220::-;1372:2;1361:9;1354:21;1335:4;1392:45;1433:2;1422:9;1418:18;1410:6;1392:45;:::i;1448:180::-;1507:6;1560:2;1548:9;1539:7;1535:23;1531:32;1528:52;;;1576:1;1573;1566:12;1528:52;-1:-1:-1;1599:23:21;;1448:180;-1:-1:-1;1448:180:21:o;1864:154::-;1950:42;1943:5;1939:54;1932:5;1929:65;1919:93;;2008:1;2005;1998:12;2023:315;2091:6;2099;2152:2;2140:9;2131:7;2127:23;2123:32;2120:52;;;2168:1;2165;2158:12;2120:52;2207:9;2194:23;2226:31;2251:5;2226:31;:::i;:::-;2276:5;2328:2;2313:18;;;;2300:32;;-1:-1:-1;;;2023:315:21:o;3073:456::-;3150:6;3158;3166;3219:2;3207:9;3198:7;3194:23;3190:32;3187:52;;;3235:1;3232;3225:12;3187:52;3274:9;3261:23;3293:31;3318:5;3293:31;:::i;:::-;3343:5;-1:-1:-1;3400:2:21;3385:18;;3372:32;3413:33;3372:32;3413:33;:::i;:::-;3073:456;;3465:7;;-1:-1:-1;;;3519:2:21;3504:18;;;;3491:32;;3073:456::o;3534:118::-;3620:5;3613:13;3606:21;3599:5;3596:32;3586:60;;3642:1;3639;3632:12;3657:241;3713:6;3766:2;3754:9;3745:7;3741:23;3737:32;3734:52;;;3782:1;3779;3772:12;3734:52;3821:9;3808:23;3840:28;3862:5;3840:28;:::i;3903:247::-;3962:6;4015:2;4003:9;3994:7;3990:23;3986:32;3983:52;;;4031:1;4028;4021:12;3983:52;4070:9;4057:23;4089:31;4114:5;4089:31;:::i;4155:184::-;4207:77;4204:1;4197:88;4304:4;4301:1;4294:15;4328:4;4325:1;4318:15;4344:334;4415:2;4409:9;4471:2;4461:13;;4476:66;4457:86;4445:99;;4574:18;4559:34;;4595:22;;;4556:62;4553:88;;;4621:18;;:::i;:::-;4657:2;4650:22;4344:334;;-1:-1:-1;4344:334:21:o;4683:465::-;4747:5;4781:18;4773:6;4770:30;4767:56;;;4803:18;;:::i;:::-;4841:116;4951:4;4882:66;4877:2;4869:6;4865:15;4861:88;4857:99;4841:116;:::i;:::-;4832:125;;4980:6;4973:5;4966:21;5020:3;5011:6;5006:3;5002:16;4999:25;4996:45;;;5037:1;5034;5027:12;4996:45;5086:6;5081:3;5074:4;5067:5;5063:16;5050:43;5140:1;5133:4;5124:6;5117:5;5113:18;5109:29;5102:40;4683:465;;;;;:::o;5153:220::-;5195:5;5248:3;5241:4;5233:6;5229:17;5225:27;5215:55;;5266:1;5263;5256:12;5215:55;5288:79;5363:3;5354:6;5341:20;5334:4;5326:6;5322:17;5288:79;:::i;5378:523::-;5464:6;5472;5480;5533:2;5521:9;5512:7;5508:23;5504:32;5501:52;;;5549:1;5546;5539:12;5501:52;5588:9;5575:23;5607:31;5632:5;5607:31;:::i;:::-;5657:5;-1:-1:-1;5713:2:21;5698:18;;5685:32;5740:18;5729:30;;5726:50;;;5772:1;5769;5762:12;5726:50;5795:49;5836:7;5827:6;5816:9;5812:22;5795:49;:::i;:::-;5785:59;;;5891:2;5880:9;5876:18;5863:32;5853:42;;5378:523;;;;;:::o;5906:367::-;5969:8;5979:6;6033:3;6026:4;6018:6;6014:17;6010:27;6000:55;;6051:1;6048;6041:12;6000:55;-1:-1:-1;6074:20:21;;6117:18;6106:30;;6103:50;;;6149:1;6146;6139:12;6103:50;6186:4;6178:6;6174:17;6162:29;;6246:3;6239:4;6229:6;6226:1;6222:14;6214:6;6210:27;6206:38;6203:47;6200:67;;;6263:1;6260;6253:12;6200:67;5906:367;;;;;:::o;6278:971::-;6418:6;6426;6434;6442;6450;6503:2;6491:9;6482:7;6478:23;6474:32;6471:52;;;6519:1;6516;6509:12;6471:52;6559:9;6546:23;6588:18;6629:2;6621:6;6618:14;6615:34;;;6645:1;6642;6635:12;6615:34;6684:70;6746:7;6737:6;6726:9;6722:22;6684:70;:::i;:::-;6773:8;;-1:-1:-1;6658:96:21;-1:-1:-1;6861:2:21;6846:18;;6833:32;;-1:-1:-1;6877:16:21;;;6874:36;;;6906:1;6903;6896:12;6874:36;6945:72;7009:7;6998:8;6987:9;6983:24;6945:72;:::i;:::-;7036:8;;-1:-1:-1;6919:98:21;-1:-1:-1;7124:2:21;7109:18;;7096:32;;-1:-1:-1;7140:16:21;;;7137:36;;;7169:1;7166;7159:12;7137:36;;7192:51;7235:7;7224:8;7213:9;7209:24;7192:51;:::i;:::-;7182:61;;;6278:971;;;;;;;;:::o;7517:450::-;7586:6;7639:2;7627:9;7618:7;7614:23;7610:32;7607:52;;;7655:1;7652;7645:12;7607:52;7695:9;7682:23;7728:18;7720:6;7717:30;7714:50;;;7760:1;7757;7750:12;7714:50;7783:22;;7836:4;7828:13;;7824:27;-1:-1:-1;7814:55:21;;7865:1;7862;7855:12;7814:55;7888:73;7953:7;7948:2;7935:16;7930:2;7926;7922:11;7888:73;:::i;7972:382::-;8037:6;8045;8098:2;8086:9;8077:7;8073:23;8069:32;8066:52;;;8114:1;8111;8104:12;8066:52;8153:9;8140:23;8172:31;8197:5;8172:31;:::i;:::-;8222:5;-1:-1:-1;8279:2:21;8264:18;;8251:32;8292:30;8251:32;8292:30;:::i;:::-;8341:7;8331:17;;;7972:382;;;;;:::o;8359:665::-;8454:6;8462;8470;8478;8531:3;8519:9;8510:7;8506:23;8502:33;8499:53;;;8548:1;8545;8538:12;8499:53;8587:9;8574:23;8606:31;8631:5;8606:31;:::i;:::-;8656:5;-1:-1:-1;8713:2:21;8698:18;;8685:32;8726:33;8685:32;8726:33;:::i;:::-;8778:7;-1:-1:-1;8832:2:21;8817:18;;8804:32;;-1:-1:-1;8887:2:21;8872:18;;8859:32;8914:18;8903:30;;8900:50;;;8946:1;8943;8936:12;8900:50;8969:49;9010:7;9001:6;8990:9;8986:22;8969:49;:::i;:::-;8959:59;;;8359:665;;;;;;;:::o;9029:456::-;9115:6;9123;9131;9184:2;9172:9;9163:7;9159:23;9155:32;9152:52;;;9200:1;9197;9190:12;9152:52;9236:9;9223:23;9213:33;;9293:2;9282:9;9278:18;9265:32;9255:42;;9348:2;9337:9;9333:18;9320:32;9375:18;9367:6;9364:30;9361:50;;;9407:1;9404;9397:12;9361:50;9430:49;9471:7;9462:6;9451:9;9447:22;9430:49;:::i;:::-;9420:59;;;9029:456;;;;;:::o;9490:1107::-;9639:6;9647;9655;9663;9671;9679;9732:3;9720:9;9711:7;9707:23;9703:33;9700:53;;;9749:1;9746;9739:12;9700:53;9788:9;9775:23;9807:31;9832:5;9807:31;:::i;:::-;9857:5;-1:-1:-1;9913:2:21;9898:18;;9885:32;9936:18;9966:14;;;9963:34;;;9993:1;9990;9983:12;9963:34;10016:49;10057:7;10048:6;10037:9;10033:22;10016:49;:::i;:::-;10006:59;;10118:2;10107:9;10103:18;10090:32;10074:48;;10147:2;10137:8;10134:16;10131:36;;;10163:1;10160;10153:12;10131:36;10202:72;10266:7;10255:8;10244:9;10240:24;10202:72;:::i;:::-;10293:8;;-1:-1:-1;10176:98:21;-1:-1:-1;10381:2:21;10366:18;;10353:32;;-1:-1:-1;10397:16:21;;;10394:36;;;10426:1;10423;10416:12;10394:36;;10465:72;10529:7;10518:8;10507:9;10503:24;10465:72;:::i;:::-;9490:1107;;;;-1:-1:-1;9490:1107:21;;-1:-1:-1;9490:1107:21;;10556:8;;9490:1107;-1:-1:-1;;;9490:1107:21:o;10602:388::-;10670:6;10678;10731:2;10719:9;10710:7;10706:23;10702:32;10699:52;;;10747:1;10744;10737:12;10699:52;10786:9;10773:23;10805:31;10830:5;10805:31;:::i;:::-;10855:5;-1:-1:-1;10912:2:21;10897:18;;10884:32;10925:33;10884:32;10925:33;:::i;10995:773::-;11117:6;11125;11133;11141;11194:2;11182:9;11173:7;11169:23;11165:32;11162:52;;;11210:1;11207;11200:12;11162:52;11250:9;11237:23;11279:18;11320:2;11312:6;11309:14;11306:34;;;11336:1;11333;11326:12;11306:34;11375:70;11437:7;11428:6;11417:9;11413:22;11375:70;:::i;:::-;11464:8;;-1:-1:-1;11349:96:21;-1:-1:-1;11552:2:21;11537:18;;11524:32;;-1:-1:-1;11568:16:21;;;11565:36;;;11597:1;11594;11587:12;11565:36;;11636:72;11700:7;11689:8;11678:9;11674:24;11636:72;:::i;:::-;10995:773;;;;-1:-1:-1;11727:8:21;-1:-1:-1;;;;10995:773:21:o;11773:1222::-;11875:6;11883;11891;11944:2;11932:9;11923:7;11919:23;11915:32;11912:52;;;11960:1;11957;11950:12;11912:52;11999:9;11986:23;12018:31;12043:5;12018:31;:::i;:::-;12068:5;-1:-1:-1;12092:2:21;12131:18;;;12118:32;12159:33;12118:32;12159:33;:::i;:::-;12211:7;-1:-1:-1;12269:2:21;12254:18;;12241:32;12292:18;12322:14;;;12319:34;;;12349:1;12346;12339:12;12319:34;12387:6;12376:9;12372:22;12362:32;;12432:7;12425:4;12421:2;12417:13;12413:27;12403:55;;12454:1;12451;12444:12;12403:55;12490:2;12477:16;12512:2;12508;12505:10;12502:36;;;12518:18;;:::i;:::-;12564:2;12561:1;12557:10;12547:20;;12587:28;12611:2;12607;12603:11;12587:28;:::i;:::-;12649:15;;;12719:11;;;12715:20;;;12680:12;;;;12747:19;;;12744:39;;;12779:1;12776;12769:12;12744:39;12803:11;;;;12823:142;12839:6;12834:3;12831:15;12823:142;;;12905:17;;12893:30;;12856:12;;;;12943;;;;12823:142;;;12984:5;12974:15;;;;;;;;11773:1222;;;;;:::o;13000:437::-;13079:1;13075:12;;;;13122;;;13143:61;;13197:4;13189:6;13185:17;13175:27;;13143:61;13250:2;13242:6;13239:14;13219:18;13216:38;13213:218;;;13287:77;13284:1;13277:88;13388:4;13385:1;13378:15;13416:4;13413:1;13406:15;13213:218;;13000:437;;;:::o;14732:184::-;14784:77;14781:1;14774:88;14881:4;14878:1;14871:15;14905:4;14902:1;14895:15;14921:128;14961:3;14992:1;14988:6;14985:1;14982:13;14979:39;;;14998:18;;:::i;:::-;-1:-1:-1;15034:9:21;;14921:128::o;16532:184::-;16584:77;16581:1;16574:88;16681:4;16678:1;16671:15;16705:4;16702:1;16695:15;17124:195;17163:3;17194:66;17187:5;17184:77;17181:103;;;17264:18;;:::i;:::-;-1:-1:-1;17311:1:21;17300:13;;17124:195::o;18074:470::-;18253:3;18291:6;18285:13;18307:53;18353:6;18348:3;18341:4;18333:6;18329:17;18307:53;:::i;:::-;18423:13;;18382:16;;;;18445:57;18423:13;18382:16;18479:4;18467:17;;18445:57;:::i;:::-;18518:20;;18074:470;-1:-1:-1;;;;18074:470:21:o;18904:125::-;18944:4;18972:1;18969;18966:8;18963:34;;;18977:18;;:::i;:::-;-1:-1:-1;19014:9:21;;18904:125::o;19381:351::-;19451:3;19483:66;19475:6;19472:78;19469:98;;;19563:1;19560;19553:12;19469:98;19599:6;19596:1;19592:14;19640:8;19633:5;19628:3;19615:34;19706:1;19668:18;;19695:13;;;-1:-1:-1;19668:18:21;;19381:351;-1:-1:-1;;19381:351:21:o;19737:579::-;20024:3;20055:58;20109:3;20101:6;20093;20055:58;:::i;:::-;20157:66;20148:6;20144:2;20140:15;20136:88;20129:5;20122:103;20241:69;20306:2;20299:5;20295:14;20287:6;20279;20241:69;:::i;:::-;20234:76;19737:579;-1:-1:-1;;;;;;;;19737:579:21:o;20321:280::-;20420:6;20473:2;20461:9;20452:7;20448:23;20444:32;20441:52;;;20489:1;20486;20479:12;20441:52;20521:9;20515:16;20540:31;20565:5;20540:31;:::i;22112:245::-;22179:6;22232:2;22220:9;22211:7;22207:23;22203:32;22200:52;;;22248:1;22245;22238:12;22200:52;22280:9;22274:16;22299:28;22321:5;22299:28;:::i;22765:184::-;22817:77;22814:1;22807:88;22914:4;22911:1;22904:15;22938:4;22935:1;22928:15;22954:120;22994:1;23020;23010:35;;23025:18;;:::i;:::-;-1:-1:-1;23059:9:21;;22954:120::o;23079:112::-;23111:1;23137;23127:35;;23142:18;;:::i;:::-;-1:-1:-1;23176:9:21;;23079:112::o;23549:512::-;23743:4;23772:42;23853:2;23845:6;23841:15;23830:9;23823:34;23905:2;23897:6;23893:15;23888:2;23877:9;23873:18;23866:43;;23945:6;23940:2;23929:9;23925:18;23918:34;23988:3;23983:2;23972:9;23968:18;23961:31;24009:46;24050:3;24039:9;24035:19;24027:6;24009:46;:::i;:::-;24001:54;23549:512;-1:-1:-1;;;;;;23549:512:21:o;24066:249::-;24135:6;24188:2;24176:9;24167:7;24163:23;24159:32;24156:52;;;24204:1;24201;24194:12;24156:52;24236:9;24230:16;24255:30;24279:5;24255:30;:::i

Swarm Source

ipfs://d41385961fb5df226d9a25f31d9e1621938c51c5053299c875de1ed2f9467647
Loading...
Loading
Loading...
Loading
[ 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.