ETH Price: $3,409.96 (-6.63%)
Gas: 7.9 Gwei

Token

Soul Sail S1-Flag (SSF)
 

Overview

Max Total Supply

1,500 SSF

Holders

880

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 SSF
0xb0cb701e415a8cf2ef8619442b152e3f07584b9f
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:
SoulSailS1Flag

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity Multiple files format)

File 19 of 20: SoulSailS1Flag.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "./Strings.sol";
import "./Ownable.sol";
import "./ERC2981.sol";
import "./Address.sol";
import "./ECDSA.sol";
import "./ERC721A.sol";
import "./DefaultOperatorFilterer.sol";
import "./ReentrancyGuard.sol";
import "./MerkleProof.sol";
import "./ERC721AQueryable.sol";

error ErrorContractMintDenied();
error ErrorNotWhiteListed();
error ErrorPulicSaleNotStarted();
error ErrorWlSaleNotStarted();
error ErrorWlSalePeriodOver();
error ErrorInsufficientFund();
error ErrorExceedTransactionLimit();
error ErrorExceedWalletLimit();
error ErrorExceedMaxSupply();

contract SoulSailS1Flag is ERC2981, ERC721A, ERC721AQueryable, Ownable, ReentrancyGuard, DefaultOperatorFilterer {
    using MerkleProof for bytes32[];
    using Address for address payable;
    using ECDSA for bytes32;
    using Strings for uint256;
    
    uint256 public _wlMintPrice = 0 ether;
    uint256 public _wlWalletLimit = 1;
    uint256 public _wlMintStartTime;

    uint256 public _mintPrice = 0 ether;
    uint256 public  _txLimit = 1;
    uint256 public  _walletLimit = 1;
    uint256 public _mintStartTime;

    uint256 public  _maxSupply = 1500;
    
    uint256 public _wlMintTimeRange = 10800;

    bool public _publicStarted = false;
    bool public _wlStarted = false;
    bool public _revealed = false;
    string public _metadataURI = "";
    string public _hiddenMetadataUri;
    bytes32 public _merkleRoot;
    
    mapping (address => uint256) public walletMinted;

    constructor() ERC721A("Soul Sail S1-Flag", "SSF") {
        _setDefaultRoyalty(owner(), 500);
    }
    
    function wlMint(bytes32[] calldata signature) external payable {
        if (tx.origin != msg.sender) revert ErrorContractMintDenied();
        if (!_wlStarted) revert ErrorWlSaleNotStarted();
        if (block.timestamp < _wlMintStartTime) revert ErrorWlSaleNotStarted();
        if (block.timestamp > _wlMintStartTime + _wlMintTimeRange)  revert ErrorWlSalePeriodOver();
        if (_wlWalletLimit + _totalMinted() > _maxSupply) revert ErrorExceedMaxSupply();
        if (!isWhitelisted(msg.sender, signature)) revert ErrorNotWhiteListed();

        uint256 userMinted = walletMinted[msg.sender];
        if (userMinted >= _wlWalletLimit) revert ErrorExceedWalletLimit();
        
        _safeMint(msg.sender, _wlWalletLimit);
        walletMinted[msg.sender] += _wlWalletLimit;
        
    }

    function pulicMint(uint256 amount) external payable {
        if (tx.origin != msg.sender) revert ErrorContractMintDenied();
        if (!_publicStarted) revert ErrorPulicSaleNotStarted();
        if (block.timestamp < _mintStartTime) revert ErrorPulicSaleNotStarted();
        if (amount + _totalMinted() > _maxSupply) revert ErrorExceedMaxSupply();
        if (amount > _txLimit) revert ErrorExceedTransactionLimit();
        
        uint256 requiredValue = amount * _mintPrice;
        uint256 userMinted = walletMinted[msg.sender];
        if (userMinted >= _walletLimit) revert ErrorExceedWalletLimit();
        if (userMinted + amount > _walletLimit) revert ErrorExceedWalletLimit();
        if (msg.value < requiredValue) revert ErrorInsufficientFund();
        
        _safeMint(msg.sender, amount);
        walletMinted[msg.sender] += amount;
        
    }
    
    function devMint(address to, uint256 amount) external onlyOwner {
        if (amount + _totalMinted() > _maxSupply) revert ErrorExceedMaxSupply();
        _safeMint(to, amount);
    }
    
    struct State {
        uint256 wlMintPrice;
        uint256 wlWalletLimit;
        uint256 mintPrice;
        uint256 txLimit;
        uint256 walletLimit;
        uint256 maxSupply;
        uint256 totalMinted;
        bool revealed;
        bool publicStarted;
        bool wlStarted; 
        uint256 mintStartTime;
        uint256 wlMintStartTime;
        uint256 wlMintTimeRange;
    }

    function _state() external view returns (State memory) {
        return
            State({
                wlMintPrice: _wlMintPrice,
                wlWalletLimit: _wlWalletLimit,
                mintPrice: _mintPrice,
                txLimit: _txLimit,
                walletLimit: _walletLimit,
                maxSupply: _maxSupply,
                totalMinted: uint256(ERC721A._totalMinted()),
                revealed: _revealed,
                publicStarted: _publicStarted,
                wlStarted: _wlStarted,
                mintStartTime: _mintStartTime,
                wlMintStartTime: _wlMintStartTime,
                wlMintTimeRange: _wlMintTimeRange
            });
    }

    function isWhitelisted(address addr, bytes32[] calldata signature) public view returns (bool) {
        bytes32 leaf = keccak256(abi.encodePacked(addr));
        return MerkleProof.verify(signature, _merkleRoot, leaf);
    }
    
    function setMerkleRoot(bytes32 merkleRoot) external onlyOwner {
        _merkleRoot = merkleRoot;
    }

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

    function setWlMintTimeRange(uint256 wlMintTimeRange) public onlyOwner {
        _wlMintTimeRange = wlMintTimeRange;
    }

    function setMintStartTime(uint256 mintStartTime) public onlyOwner {
        _mintStartTime = mintStartTime;
    }
    
    function setWlMintStartTime(uint256 wlMintStartTime) public onlyOwner {
        _wlMintStartTime = wlMintStartTime;
    }

    function setWlWalletLimit(uint256 wlWalletLimit) public onlyOwner {
        _wlWalletLimit = wlWalletLimit;
    } 
    
    function setWlMintPrice(uint256 wlMintPrice) public onlyOwner {
        _wlMintPrice = wlMintPrice;
    }

    function setTxLimit(uint256 txLimit) public onlyOwner {
        _txLimit = txLimit;
    }
    
    function setWalletLimit(uint256 walletLimit) public onlyOwner {
        _walletLimit = walletLimit;
    } 

    function setMintPrice(uint256 mintPrice) public onlyOwner {
        _mintPrice = mintPrice;
    }
    
    function setMaxSupply(uint256 maxSupply) public onlyOwner {
        _maxSupply = maxSupply;
    } 

    function setRevealed(bool revealed) public onlyOwner {
        _revealed = revealed;
    }
 
    function setPublicStarted(bool publicStarted) external onlyOwner {
        _publicStarted = publicStarted;
    }
    
    function setWlStarted(bool wlStarted) external onlyOwner {
        _wlStarted = wlStarted;
    }

    function setMetadataURI(string memory uri) external onlyOwner {
        _metadataURI = uri;
    }

    function setHiddenMetadataUri(string memory hiddenMetadataUri) public onlyOwner {
        _hiddenMetadataUri = hiddenMetadataUri;
    }
    
    function setFeeNumerator(uint96 feeNumerator) external onlyOwner {
        _setDefaultRoyalty(owner(), feeNumerator);
    }

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        if (_revealed == false) {
            return _hiddenMetadataUri;
        }

        string memory baseURI = _metadataURI;
        return string(abi.encodePacked(baseURI, tokenId.toString(), ".json"));
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC2981, ERC721A) returns (bool) {
        return
            interfaceId == type(IERC2981).interfaceId ||
            interfaceId == type(IERC721).interfaceId ||
            super.supportsInterface(interfaceId);
    } 
  
    function withdraw() external onlyOwner nonReentrant{
        payable(msg.sender).sendValue(address(this).balance);
    }
	
	function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {
		super.setApprovalForAll(operator, approved);
	}

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

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

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

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

File 1 of 20: Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return 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 20: Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

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

import "./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 20: ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "./Strings.sol";

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

File 5 of 20: ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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 6 of 20: ERC2981.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/common/ERC2981.sol)

pragma solidity ^0.8.0;

import "./IERC2981.sol";
import "./ERC165.sol";

/**
 * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
 *
 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
 *
 * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
 * fee is specified in basis points by default.
 *
 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
 *
 * _Available since v4.5._
 */
abstract contract ERC2981 is IERC2981, ERC165 {
    struct RoyaltyInfo {
        address receiver;
        uint96 royaltyFraction;
    }

    RoyaltyInfo private _defaultRoyaltyInfo;
    mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;

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

    /**
     * @inheritdoc IERC2981
     */
    function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) {
        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];

        if (royalty.receiver == address(0)) {
            royalty = _defaultRoyaltyInfo;
        }

        uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator();

        return (royalty.receiver, royaltyAmount);
    }

    /**
     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
     * override.
     */
    function _feeDenominator() internal pure virtual returns (uint96) {
        return 10000;
    }

    /**
     * @dev Sets the royalty information that all ids in this contract will default to.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: invalid receiver");

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Removes default royalty information.
     */
    function _deleteDefaultRoyalty() internal virtual {
        delete _defaultRoyaltyInfo;
    }

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `tokenId` must be already minted.
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(
        uint256 tokenId,
        address receiver,
        uint96 feeNumerator
    ) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: Invalid parameters");

        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Resets royalty information for the token id back to the global default.
     */
    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
        delete _tokenRoyaltyInfo[tokenId];
    }
}

File 7 of 20: ERC721A.sol
// SPDX-License-Identifier: MIT
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721.sol';
import './IERC721Receiver.sol';
import './IERC721Metadata.sol';
import './Address.sol';
import './Context.sol';
import './Strings.sol';
import './ERC165.sol';

error ApprovalCallerNotOwnerNorApproved();
error ApprovalQueryForNonexistentToken();
error ApproveToCaller();
error ApprovalToCurrentOwner();
error BalanceQueryForZeroAddress();
error MintToZeroAddress();
error MintZeroQuantity();
error OwnerQueryForNonexistentToken();
error TransferCallerNotOwnerNorApproved();
error TransferFromIncorrectOwner();
error TransferToNonERC721ReceiverImplementer();
error TransferToZeroAddress();
error URIQueryForNonexistentToken();

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Compiler will pack this into a single 256bit word.
    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

    // Compiler will pack this into a single 256bit word.
    struct AddressData {
        // Realistically, 2**64-1 is more than enough.
        uint64 balance;
        // Keeps track of mint count with minimal overhead for tokenomics.
        uint64 numberMinted;
        // Keeps track of burn count with minimal overhead for tokenomics.
        uint64 numberBurned;
        // For miscellaneous variable(s) pertaining to the address
        // (e.g. number of whitelist mint slots used).
        // If there are multiple variables, please pack them into a uint64.
        uint64 aux;
    }

    // The tokenId of the next token to be minted.
    uint256 internal _currentIndex;

    // The number of tokens burned.
    uint256 internal _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 _ownershipOf implementation for details.
    mapping(uint256 => TokenOwnership) internal _ownerships;

    // Mapping owner address to address data
    mapping(address => AddressData) private _addressData;

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

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

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

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

    /**
     * @dev Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens.
     */
    function totalSupply() public view returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than _currentIndex - _startTokenId() times
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

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

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return uint256(_addressData[owner].balance);
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return uint256(_addressData[owner].numberMinted);
    }

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

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

    /**
     * Sets the auxillary 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 {
        _addressData[owner].aux = aux;
    }

    /**
     * Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around in the collection over time.
     */
    function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr && curr < _currentIndex) {
                TokenOwnership memory ownership = _ownerships[curr];
                if (!ownership.burned) {
                    if (ownership.addr != address(0)) {
                        return ownership;
                    }
                    // Invariant:
                    // There will always be an ownership that has an address and is not burned
                    // before an ownership that does not have an address and is not burned.
                    // Hence, curr will not underflow.
                    while (true) {
                        curr--;
                        ownership = _ownerships[curr];
                        if (ownership.addr != address(0)) {
                            return ownership;
                        }
                    }
                }
            }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        return _ownershipOf(tokenId).addr;
    }

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

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

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

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

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

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721A.ownerOf(tokenId);
        if (to == owner) revert ApprovalToCurrentOwner();

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

        _approve(to, tokenId, owner);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

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

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

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

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

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        _transfer(from, to, tokenId);
        if (to.isContract() && !_checkContractOnERC721Received(from, to, tokenId, _data)) {
            revert TransferToNonERC721ReceiverImplementer();
        }
    }

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

    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, '');
    }

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

    /**
     * @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.
     */
    function _mint(
        address to,
        uint256 quantity,
        bytes memory _data,
        bool safe
    ) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            if (safe && to.isContract()) {
                do {
                    emit Transfer(address(0), to, updatedIndex);
                    if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (updatedIndex != end);
                // Reentrancy protection
                if (_currentIndex != startTokenId) revert();
            } else {
                do {
                    emit Transfer(address(0), to, updatedIndex++);
                } while (updatedIndex != end);
            }
            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) private {
        TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

        if (prevOwnership.addr != from) revert TransferFromIncorrectOwner();

        bool isApprovedOrOwner = (_msgSender() == from ||
            isApprovedForAll(from, _msgSender()) ||
            getApproved(tokenId) == _msgSender());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId, from);

        // 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 {
            _addressData[from].balance -= 1;
            _addressData[to].balance += 1;

            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = to;
            currSlot.startTimestamp = uint64(block.timestamp);

            // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

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

    /**
     * @dev This is 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 {
        TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

        address from = prevOwnership.addr;

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSender() == from ||
                isApprovedForAll(from, _msgSender()) ||
                getApproved(tokenId) == _msgSender());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

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

        // Clear approvals from the previous owner
        _approve(address(0), tokenId, from);

        // 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 {
            AddressData storage addressData = _addressData[from];
            addressData.balance -= 1;
            addressData.numberBurned += 1;

            // Keep track of who burned the token, and the timestamp of burning.
            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = from;
            currSlot.startTimestamp = uint64(block.timestamp);
            currSlot.burned = true;

            // If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

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

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

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(
        address to,
        uint256 tokenId,
        address owner
    ) private {
        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

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

    /**
     * @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 {}
}

File 8 of 20: ERC721AQueryable.sol
// SPDX-License-Identifier: MIT
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './ERC721A.sol';

error InvalidQueryRange();

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

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

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

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

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

pragma solidity ^0.8.0;

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

File 10 of 20: IERC2981.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

File 11 of 20: IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.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`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

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

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

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

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

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

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

File 12 of 20: IERC721Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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 13 of 20: IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

File 14 of 20: IOperatorFilterRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

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

File 15 of 20: MerkleProof.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 16 of 20: OperatorFilterer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import "./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 17 of 20: Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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 18 of 20: ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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 20 of 20: Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"ErrorContractMintDenied","type":"error"},{"inputs":[],"name":"ErrorExceedMaxSupply","type":"error"},{"inputs":[],"name":"ErrorExceedTransactionLimit","type":"error"},{"inputs":[],"name":"ErrorExceedWalletLimit","type":"error"},{"inputs":[],"name":"ErrorInsufficientFund","type":"error"},{"inputs":[],"name":"ErrorNotWhiteListed","type":"error"},{"inputs":[],"name":"ErrorPulicSaleNotStarted","type":"error"},{"inputs":[],"name":"ErrorWlSaleNotStarted","type":"error"},{"inputs":[],"name":"ErrorWlSalePeriodOver","type":"error"},{"inputs":[],"name":"InvalidQueryRange","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":"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":"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":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_hiddenMetadataUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_metadataURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_mintStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_publicStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_state","outputs":[{"components":[{"internalType":"uint256","name":"wlMintPrice","type":"uint256"},{"internalType":"uint256","name":"wlWalletLimit","type":"uint256"},{"internalType":"uint256","name":"mintPrice","type":"uint256"},{"internalType":"uint256","name":"txLimit","type":"uint256"},{"internalType":"uint256","name":"walletLimit","type":"uint256"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"uint256","name":"totalMinted","type":"uint256"},{"internalType":"bool","name":"revealed","type":"bool"},{"internalType":"bool","name":"publicStarted","type":"bool"},{"internalType":"bool","name":"wlStarted","type":"bool"},{"internalType":"uint256","name":"mintStartTime","type":"uint256"},{"internalType":"uint256","name":"wlMintStartTime","type":"uint256"},{"internalType":"uint256","name":"wlMintTimeRange","type":"uint256"}],"internalType":"struct SoulSailS1Flag.State","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_txLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_walletLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_wlMintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_wlMintStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_wlMintTimeRange","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_wlStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_wlWalletLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"devMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"}],"internalType":"struct ERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"}],"internalType":"struct ERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bytes32[]","name":"signature","type":"bytes32[]"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"pulicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"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":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setFeeNumerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"hiddenMetadataUri","type":"string"}],"name":"setHiddenMetadataUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setMetadataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mintPrice","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mintStartTime","type":"uint256"}],"name":"setMintStartTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"publicStarted","type":"bool"}],"name":"setPublicStarted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"revealed","type":"bool"}],"name":"setRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"txLimit","type":"uint256"}],"name":"setTxLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"walletLimit","type":"uint256"}],"name":"setWalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"wlMintPrice","type":"uint256"}],"name":"setWlMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"wlMintStartTime","type":"uint256"}],"name":"setWlMintStartTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"wlMintTimeRange","type":"uint256"}],"name":"setWlMintTimeRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"wlStarted","type":"bool"}],"name":"setWlStarted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"wlWalletLimit","type":"uint256"}],"name":"setWlWalletLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"walletMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"signature","type":"bytes32[]"}],"name":"wlMint","outputs":[],"stateMutability":"payable","type":"function"}]

6000600c8190556001600d819055600f82905560108190556011556105dc601355612a306014556015805462ffffff1916905560a0604081905260808290526200004d9160169190620003b5565b503480156200005b57600080fd5b506040805180820182526011815270536f756c205361696c2053312d466c616760781b60208083019182528351808501909452600384526229a9a360e91b908401528151733cc6cdda760b79bafa08df41ecfa224f810dceb693600193929091620000c991600491620003b5565b508051620000df906005906020840190620003b5565b5050600160025550620000f2336200025e565b6001600b556daaeb6d7670e522a718067333cd4e3b156200023c5780156200018a57604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b1580156200016b57600080fd5b505af115801562000180573d6000803e3d6000fd5b505050506200023c565b6001600160a01b03821615620001db5760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af29039060440162000150565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b1580156200022257600080fd5b505af115801562000237573d6000803e3d6000fd5b505050505b5050600a5462000258906001600160a01b03166101f4620002b0565b62000497565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6127106001600160601b0382161115620003245760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084015b60405180910390fd5b6001600160a01b0382166200037c5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c69642072656365697665720000000000000060448201526064016200031b565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600055565b828054620003c3906200045b565b90600052602060002090601f016020900481019282620003e7576000855562000432565b82601f106200040257805160ff191683800117855562000432565b8280016001018555821562000432579182015b828111156200043257825182559160200191906001019062000415565b506200044092915062000444565b5090565b5b8082111562000440576000815560010162000445565b600181811c908216806200047057607f821691505b6020821081036200049157634e487b7160e01b600052602260045260246000fd5b50919050565b61353580620004a76000396000f3fe6080604052600436106103a25760003560e01c806370a08231116101e7578063a22cb4651161010d578063d5b3621b116100a0578063f1d5f5171161006f578063f1d5f51714610a9c578063f2fde38b14610abc578063f4a0a52814610adc578063fc5384d814610afc57600080fd5b8063d5b3621b14610a1d578063e0a8085314610a3d578063e52c837514610a5d578063e985e9c514610a7c57600080fd5b8063c87b56dd116100dc578063c87b56dd1461099b578063d3738fc8146109bb578063d41f4dd2146109e8578063d4a6762314610a0857600080fd5b8063a22cb4651461091b578063b0ea7dcf1461093b578063b88d4fde1461094e578063c23dc68f1461096e57600080fd5b80638a69a5d9116101855780639418163a116101545780639418163a146108aa57806395d89b41146108c457806399a2557a146108d9578063a1cb31b7146108f957600080fd5b80638a69a5d91461084b5780638bc59ebc146108605780638da5cb5b1461087657806392ec8a471461089457600080fd5b8063750521f5116101c1578063750521f5146107be5780637cb64759146107de5780637e567acd146107fe5780638462151c1461081e57600080fd5b806370a0823114610773578063715018a61461079357806372836f35146107a857600080fd5b806341f43434116102cc5780635bbb21771161026a57806363553e7c1161023957806363553e7c146106fd578063653a819e146107135780636ebeac85146107335780636f8b44b01461075357600080fd5b80635bbb2177146106705780635c85974f1461069d578063627804af146106bd5780636352211e146106dd57600080fd5b806345bc00df116102a657806345bc00df146105fa5780634656750a1461061a5780634fdd43cb146106305780635a23dd991461065057600080fd5b806341f434341461059857806342676e6c146105ba57806342842e0e146105da57600080fd5b80630e2351e2116103445780632a55205a116103135780632a55205a1461050e5780632fc37ab21461054d5780633ccfd60b146105635780633d2722941461057857600080fd5b80630e2351e2146104a557806318160ddd146104bb57806322f4596f146104d857806323b872dd146104ee57600080fd5b806306fdde031161038057806306fdde0314610415578063081812fc14610437578063095ea7b31461046f5780630c6767341461048f57600080fd5b806301ffc9a7146103a75780630215bc7d146103dc5780630387da42146103f1575b600080fd5b3480156103b357600080fd5b506103c76103c2366004612c66565b610b1c565b60405190151581526020015b60405180910390f35b6103ef6103ea366004612c83565b610b62565b005b3480156103fd57600080fd5b50610407600f5481565b6040519081526020016103d3565b34801561042157600080fd5b5061042a610ce4565b6040516103d39190612cf4565b34801561044357600080fd5b50610457610452366004612c83565b610d76565b6040516001600160a01b0390911681526020016103d3565b34801561047b57600080fd5b506103ef61048a366004612d23565b610dba565b34801561049b57600080fd5b50610407600c5481565b3480156104b157600080fd5b5061040760115481565b3480156104c757600080fd5b506003546002540360001901610407565b3480156104e457600080fd5b5061040760135481565b3480156104fa57600080fd5b506103ef610509366004612d4d565b610dd3565b34801561051a57600080fd5b5061052e610529366004612d89565b610dfe565b604080516001600160a01b0390931683526020830191909152016103d3565b34801561055957600080fd5b5061040760185481565b34801561056f57600080fd5b506103ef610eac565b34801561058457600080fd5b506103ef610593366004612c83565b610f47565b3480156105a457600080fd5b506104576daaeb6d7670e522a718067333cd4e81565b3480156105c657600080fd5b506103ef6105d5366004612c83565b610f76565b3480156105e657600080fd5b506103ef6105f5366004612d4d565b610fa5565b34801561060657600080fd5b506103ef610615366004612db9565b610fca565b34801561062657600080fd5b5061040760145481565b34801561063c57600080fd5b506103ef61064b366004612e73565b61100e565b34801561065c57600080fd5b506103c761066b366004612eff565b61104f565b34801561067c57600080fd5b5061069061068b366004612f51565b6110d7565b6040516103d39190612ff6565b3480156106a957600080fd5b506103ef6106b8366004612c83565b61119d565b3480156106c957600080fd5b506103ef6106d8366004612d23565b6111cc565b3480156106e957600080fd5b506104576106f8366004612c83565b611233565b34801561070957600080fd5b5061040760105481565b34801561071f57600080fd5b506103ef61072e366004613060565b611245565b34801561073f57600080fd5b506015546103c79062010000900460ff1681565b34801561075f57600080fd5b506103ef61076e366004612c83565b61128d565b34801561077f57600080fd5b5061040761078e366004613089565b6112bc565b34801561079f57600080fd5b506103ef61130a565b3480156107b457600080fd5b5061040760125481565b3480156107ca57600080fd5b506103ef6107d9366004612e73565b611340565b3480156107ea57600080fd5b506103ef6107f9366004612c83565b61137d565b34801561080a57600080fd5b506103ef610819366004612db9565b6113ac565b34801561082a57600080fd5b5061083e610839366004613089565b6113e9565b6040516103d391906130a4565b34801561085757600080fd5b5061042a61152e565b34801561086c57600080fd5b50610407600e5481565b34801561088257600080fd5b50600a546001600160a01b0316610457565b3480156108a057600080fd5b50610407600d5481565b3480156108b657600080fd5b506015546103c79060ff1681565b3480156108d057600080fd5b5061042a6115bc565b3480156108e557600080fd5b5061083e6108f43660046130dc565b6115cb565b34801561090557600080fd5b5061090e61178c565b6040516103d3919061310f565b34801561092757600080fd5b506103ef6109363660046131ae565b611892565b6103ef6109493660046131e5565b6118a6565b34801561095a57600080fd5b506103ef610969366004613226565b6119ff565b34801561097a57600080fd5b5061098e610989366004612c83565b611a2c565b6040516103d391906132a1565b3480156109a757600080fd5b5061042a6109b6366004612c83565b611ae6565b3480156109c757600080fd5b506104076109d6366004613089565b60196020526000908152604090205481565b3480156109f457600080fd5b506103ef610a03366004612c83565b611c76565b348015610a1457600080fd5b5061042a611ca5565b348015610a2957600080fd5b506103ef610a38366004612c83565b611cb2565b348015610a4957600080fd5b506103ef610a58366004612db9565b611ce1565b348015610a6957600080fd5b506015546103c790610100900460ff1681565b348015610a8857600080fd5b506103c7610a973660046132d6565b611d27565b348015610aa857600080fd5b506103ef610ab7366004612c83565b611d55565b348015610ac857600080fd5b506103ef610ad7366004613089565b611d84565b348015610ae857600080fd5b506103ef610af7366004612c83565b611e1c565b348015610b0857600080fd5b506103ef610b17366004612c83565b611e4b565b60006001600160e01b0319821663152a902d60e11b1480610b4d57506001600160e01b031982166380ac58cd60e01b145b80610b5c5750610b5c82611e7a565b92915050565b323314610b82576040516367f91f7760e11b815260040160405180910390fd5b60155460ff16610ba557604051634c45182560e11b815260040160405180910390fd5b601254421015610bc857604051634c45182560e11b815260040160405180910390fd5b60135460025460001901610bdc908361331f565b1115610bfb57604051630af76cd360e31b815260040160405180910390fd5b601054811115610c1e5760405163552d9c8360e01b815260040160405180910390fd5b6000600f5482610c2e9190613337565b33600090815260196020526040902054601154919250908110610c64576040516305c6e3a560e21b815260040160405180910390fd5b601154610c71848361331f565b1115610c90576040516305c6e3a560e21b815260040160405180910390fd5b81341015610cb15760405163272c430f60e21b815260040160405180910390fd5b610cbb3384611eba565b3360009081526019602052604081208054859290610cda90849061331f565b9091555050505050565b606060048054610cf390613356565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1f90613356565b8015610d6c5780601f10610d4157610100808354040283529160200191610d6c565b820191906000526020600020905b815481529060010190602001808311610d4f57829003601f168201915b5050505050905090565b6000610d8182611ed4565b610d9e576040516333d1c03960e21b815260040160405180910390fd5b506000908152600860205260409020546001600160a01b031690565b81610dc481611f0d565b610dce8383611fc6565b505050565b826001600160a01b0381163314610ded57610ded33611f0d565b610df884848461204e565b50505050565b60008281526001602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610e735750604080518082019091526000546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610e92906001600160601b031687613337565b610e9c91906133a6565b91519350909150505b9250929050565b600a546001600160a01b03163314610edf5760405162461bcd60e51b8152600401610ed6906133ba565b60405180910390fd5b6002600b5403610f315760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ed6565b6002600b55610f403347612059565b6001600b55565b600a546001600160a01b03163314610f715760405162461bcd60e51b8152600401610ed6906133ba565b600c55565b600a546001600160a01b03163314610fa05760405162461bcd60e51b8152600401610ed6906133ba565b600e55565b826001600160a01b0381163314610fbf57610fbf33611f0d565b610df8848484612172565b600a546001600160a01b03163314610ff45760405162461bcd60e51b8152600401610ed6906133ba565b601580549115156101000261ff0019909216919091179055565b600a546001600160a01b031633146110385760405162461bcd60e51b8152600401610ed6906133ba565b805161104b906017906020840190612bb7565b5050565b6040516bffffffffffffffffffffffff19606085901b16602082015260009081906034016040516020818303038152906040528051906020012090506110cc84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050601854915084905061218d565b9150505b9392505050565b80516060906000816001600160401b038111156110f6576110f6612dd6565b60405190808252806020026020018201604052801561114157816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816111145790505b50905060005b82811461119557611170858281518110611163576111636133ef565b6020026020010151611a2c565b828281518110611182576111826133ef565b6020908102919091010152600101611147565b509392505050565b600a546001600160a01b031633146111c75760405162461bcd60e51b8152600401610ed6906133ba565b601055565b600a546001600160a01b031633146111f65760405162461bcd60e51b8152600401610ed6906133ba565b6013546002546000190161120a908361331f565b111561122957604051630af76cd360e31b815260040160405180910390fd5b61104b8282611eba565b600061123e826121a3565b5192915050565b600a546001600160a01b0316331461126f5760405162461bcd60e51b8152600401610ed6906133ba565b61128a611284600a546001600160a01b031690565b826122ca565b50565b600a546001600160a01b031633146112b75760405162461bcd60e51b8152600401610ed6906133ba565b601355565b60006001600160a01b0382166112e5576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600760205260409020546001600160401b031690565b600a546001600160a01b031633146113345760405162461bcd60e51b8152600401610ed6906133ba565b61133e60006123c7565b565b600a546001600160a01b0316331461136a5760405162461bcd60e51b8152600401610ed6906133ba565b805161104b906016906020840190612bb7565b600a546001600160a01b031633146113a75760405162461bcd60e51b8152600401610ed6906133ba565b601855565b600a546001600160a01b031633146113d65760405162461bcd60e51b8152600401610ed6906133ba565b6015805460ff1916911515919091179055565b606060008060006113f9856112bc565b90506000816001600160401b0381111561141557611415612dd6565b60405190808252806020026020018201604052801561143e578160200160208202803683370190505b509050611464604080516060810182526000808252602082018190529181019190915290565b60015b83861461152257600081815260066020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161515918101829052925061151a5781516001600160a01b0316156114db57815194505b876001600160a01b0316856001600160a01b03160361151a578083878060010198508151811061150d5761150d6133ef565b6020026020010181815250505b600101611467565b50909695505050505050565b6017805461153b90613356565b80601f016020809104026020016040519081016040528092919081815260200182805461156790613356565b80156115b45780601f10611589576101008083540402835291602001916115b4565b820191906000526020600020905b81548152906001019060200180831161159757829003601f168201915b505050505081565b606060058054610cf390613356565b60608183106115ed57604051631960ccad60e11b815260040160405180910390fd5b600254600090600185101561160157600194505b8084111561160d578093505b6000611618876112bc565b9050848610156116375785850381811015611631578091505b5061163b565b5060005b6000816001600160401b0381111561165557611655612dd6565b60405190808252806020026020018201604052801561167e578160200160208202803683370190505b509050816000036116945793506110d092505050565b600061169f88611a2c565b9050600081604001516116b0575080515b885b8881141580156116c25750848714155b1561177b57600081815260066020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff16151591810182905293506117735782516001600160a01b03161561173457825191505b8a6001600160a01b0316826001600160a01b0316036117735780848880600101995081518110611766576117666133ef565b6020026020010181815250505b6001016116b2565b505050928352509095945050505050565b6117fd604051806101a00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581526020016000151581526020016000151581526020016000815260200160008152602001600081525090565b604051806101a00160405280600c548152602001600d548152602001600f5481526020016010548152602001601154815260200160135481526020016118466002546000190190565b815260155460ff6201000082048116151560208401528082161515604084015261010090910416151560608201526012546080820152600e5460a082015260145460c090910152919050565b8161189c81611f0d565b610dce8383612419565b3233146118c6576040516367f91f7760e11b815260040160405180910390fd5b601554610100900460ff166118ee57604051638380787360e01b815260040160405180910390fd5b600e5442101561191157604051638380787360e01b815260040160405180910390fd5b601454600e54611921919061331f565b42111561194157604051631a3b6d8960e21b815260040160405180910390fd5b60135460025460001901600d54611958919061331f565b111561197757604051630af76cd360e31b815260040160405180910390fd5b61198233838361104f565b61199f5760405163b14a633d60e01b815260040160405180910390fd5b33600090815260196020526040902054600d5481106119d1576040516305c6e3a560e21b815260040160405180910390fd5b6119dd33600d54611eba565b600d543360009081526019602052604081208054909190610cda90849061331f565b836001600160a01b0381163314611a1957611a1933611f0d565b611a25858585856124ae565b5050505050565b60408051606080820183526000808352602080840182905283850182905284519283018552818352820181905292810192909252906001831080611a7257506002548310155b15611a7d5792915050565b50600082815260066020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161580159282019290925290611add5792915050565b6110d0836121a3565b6060611af182611ed4565b611b0e57604051630a14c4b560e41b815260040160405180910390fd5b60155462010000900460ff161515600003611bb55760178054611b3090613356565b80601f0160208091040260200160405190810160405280929190818152602001828054611b5c90613356565b8015611ba95780601f10611b7e57610100808354040283529160200191611ba9565b820191906000526020600020905b815481529060010190602001808311611b8c57829003601f168201915b50505050509050919050565b600060168054611bc490613356565b80601f0160208091040260200160405190810160405280929190818152602001828054611bf090613356565b8015611c3d5780601f10611c1257610100808354040283529160200191611c3d565b820191906000526020600020905b815481529060010190602001808311611c2057829003601f168201915b5050505050905080611c4e846124f9565b604051602001611c5f929190613405565b604051602081830303815290604052915050919050565b600a546001600160a01b03163314611ca05760405162461bcd60e51b8152600401610ed6906133ba565b600d55565b6016805461153b90613356565b600a546001600160a01b03163314611cdc5760405162461bcd60e51b8152600401610ed6906133ba565b601255565b600a546001600160a01b03163314611d0b5760405162461bcd60e51b8152600401610ed6906133ba565b60158054911515620100000262ff000019909216919091179055565b6001600160a01b03918216600090815260096020908152604080832093909416825291909152205460ff1690565b600a546001600160a01b03163314611d7f5760405162461bcd60e51b8152600401610ed6906133ba565b601155565b600a546001600160a01b03163314611dae5760405162461bcd60e51b8152600401610ed6906133ba565b6001600160a01b038116611e135760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ed6565b61128a816123c7565b600a546001600160a01b03163314611e465760405162461bcd60e51b8152600401610ed6906133ba565b600f55565b600a546001600160a01b03163314611e755760405162461bcd60e51b8152600401610ed6906133ba565b601455565b60006001600160e01b031982166380ac58cd60e01b1480611eab57506001600160e01b03198216635b5e139f60e01b145b80610b5c5750610b5c82612601565b61104b828260405180602001604052806000815250612636565b600081600111158015611ee8575060025482105b8015610b5c575050600090815260066020526040902054600160e01b900460ff161590565b6daaeb6d7670e522a718067333cd4e3b1561128a57604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611f7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9e9190613444565b61128a57604051633b79c77360e21b81526001600160a01b0382166004820152602401610ed6565b6000611fd182611233565b9050806001600160a01b0316836001600160a01b0316036120055760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b0382161480159061202557506120238133611d27565b155b15612043576040516367d9dca160e11b815260040160405180910390fd5b610dce838383612643565b610dce83838361269f565b804710156120a95760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610ed6565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146120f6576040519150601f19603f3d011682016040523d82523d6000602084013e6120fb565b606091505b5050905080610dce5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610ed6565b610dce838383604051806020016040528060008152506119ff565b60008261219a858461288a565b14949350505050565b604080516060810182526000808252602082018190529181019190915281806001111580156121d3575060025481105b156122b157600081815260066020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161515918101829052906122af5780516001600160a01b031615612246579392505050565b5060001901600081815260066020908152604091829020825160608101845290546001600160a01b038116808352600160a01b82046001600160401b031693830193909352600160e01b900460ff16151592810192909252156122aa579392505050565b612246565b505b604051636f96cda160e11b815260040160405180910390fd5b6127106001600160601b03821611156123385760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401610ed6565b6001600160a01b03821661238e5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610ed6565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600055565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b336001600160a01b038316036124425760405163b06307db60e01b815260040160405180910390fd5b3360008181526009602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6124b984848461269f565b6001600160a01b0383163b151580156124db57506124d9848484846128cf565b155b15610df8576040516368d2bf6b60e11b815260040160405180910390fd5b6060816000036125205750506040805180820190915260018152600360fc1b602082015290565b8160005b811561254a578061253481613461565b91506125439050600a836133a6565b9150612524565b6000816001600160401b0381111561256457612564612dd6565b6040519080825280601f01601f19166020018201604052801561258e576020820181803683370190505b5090505b84156125f9576125a360018361347a565b91506125b0600a86613491565b6125bb90603061331f565b60f81b8183815181106125d0576125d06133ef565b60200101906001600160f81b031916908160001a9053506125f2600a866133a6565b9450612592565b949350505050565b60006001600160e01b0319821663152a902d60e11b1480610b5c57506301ffc9a760e01b6001600160e01b0319831614610b5c565b610dce83838360016129ba565b60008281526008602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b60006126aa826121a3565b9050836001600160a01b031681600001516001600160a01b0316146126e15760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b03861614806126ff57506126ff8533611d27565b8061271a57503361270f84610d76565b6001600160a01b0316145b90508061273a57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03841661276157604051633a954ecd60e21b815260040160405180910390fd5b61276d60008487612643565b6001600160a01b038581166000908152600760209081526040808320805467ffffffffffffffff198082166001600160401b0392831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600690945282852080546001600160e01b031916909417600160a01b4290921691909102178355870180845292208054919390911661284157600254821461284157805460208601516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038a16171781555b50505082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611a25565b600081815b8451811015611195576128bb828683815181106128ae576128ae6133ef565b6020026020010151612b8b565b9150806128c781613461565b91505061288f565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906129049033908990889088906004016134a5565b6020604051808303816000875af192505050801561293f575060408051601f3d908101601f1916820190925261293c918101906134e2565b60015b61299d573d80801561296d576040519150601f19603f3d011682016040523d82523d6000602084013e612972565b606091505b508051600003612995576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b6002546001600160a01b0385166129e357604051622e076360e81b815260040160405180910390fd5b83600003612a045760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038516600081815260076020908152604080832080546fffffffffffffffffffffffffffffffff1981166001600160401b038083168c0181169182176801000000000000000067ffffffffffffffff1990941690921783900481168c01811690920217909155858452600690925290912080546001600160e01b031916909217600160a01b429092169190910217905580808501838015612ab557506001600160a01b0387163b15155b15612b3d575b60405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4612b0660008884806001019550886128cf565b612b23576040516368d2bf6b60e11b815260040160405180910390fd5b808203612abb578260025414612b3857600080fd5b612b82565b5b6040516001830192906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4808203612b3e575b50600255611a25565b6000818310612ba75760008281526020849052604090206110d0565b5060009182526020526040902090565b828054612bc390613356565b90600052602060002090601f016020900481019282612be55760008555612c2b565b82601f10612bfe57805160ff1916838001178555612c2b565b82800160010185558215612c2b579182015b82811115612c2b578251825591602001919060010190612c10565b50612c37929150612c3b565b5090565b5b80821115612c375760008155600101612c3c565b6001600160e01b03198116811461128a57600080fd5b600060208284031215612c7857600080fd5b81356110d081612c50565b600060208284031215612c9557600080fd5b5035919050565b60005b83811015612cb7578181015183820152602001612c9f565b83811115610df85750506000910152565b60008151808452612ce0816020860160208601612c9c565b601f01601f19169290920160200192915050565b6020815260006110d06020830184612cc8565b80356001600160a01b0381168114612d1e57600080fd5b919050565b60008060408385031215612d3657600080fd5b612d3f83612d07565b946020939093013593505050565b600080600060608486031215612d6257600080fd5b612d6b84612d07565b9250612d7960208501612d07565b9150604084013590509250925092565b60008060408385031215612d9c57600080fd5b50508035926020909101359150565b801515811461128a57600080fd5b600060208284031215612dcb57600080fd5b81356110d081612dab565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612e1457612e14612dd6565b604052919050565b60006001600160401b03831115612e3557612e35612dd6565b612e48601f8401601f1916602001612dec565b9050828152838383011115612e5c57600080fd5b828260208301376000602084830101529392505050565b600060208284031215612e8557600080fd5b81356001600160401b03811115612e9b57600080fd5b8201601f81018413612eac57600080fd5b6125f984823560208401612e1c565b60008083601f840112612ecd57600080fd5b5081356001600160401b03811115612ee457600080fd5b6020830191508360208260051b8501011115610ea557600080fd5b600080600060408486031215612f1457600080fd5b612f1d84612d07565b925060208401356001600160401b03811115612f3857600080fd5b612f4486828701612ebb565b9497909650939450505050565b60006020808385031215612f6457600080fd5b82356001600160401b0380821115612f7b57600080fd5b818501915085601f830112612f8f57600080fd5b813581811115612fa157612fa1612dd6565b8060051b9150612fb2848301612dec565b8181529183018401918481019088841115612fcc57600080fd5b938501935b83851015612fea57843582529385019390850190612fd1565b98975050505050505050565b6020808252825182820181905260009190848201906040850190845b818110156115225761304d83855180516001600160a01b031682526020808201516001600160401b0316908301526040908101511515910152565b9284019260609290920191600101613012565b60006020828403121561307257600080fd5b81356001600160601b03811681146110d057600080fd5b60006020828403121561309b57600080fd5b6110d082612d07565b6020808252825182820181905260009190848201906040850190845b81811015611522578351835292840192918401916001016130c0565b6000806000606084860312156130f157600080fd5b6130fa84612d07565b95602085013595506040909401359392505050565b60006101a082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015161316b60e084018215159052565b5061010083810151151590830152610120808401511515908301526101408084015190830152610160808401519083015261018092830151929091019190915290565b600080604083850312156131c157600080fd5b6131ca83612d07565b915060208301356131da81612dab565b809150509250929050565b600080602083850312156131f857600080fd5b82356001600160401b0381111561320e57600080fd5b61321a85828601612ebb565b90969095509350505050565b6000806000806080858703121561323c57600080fd5b61324585612d07565b935061325360208601612d07565b92506040850135915060608501356001600160401b0381111561327557600080fd5b8501601f8101871361328657600080fd5b61329587823560208401612e1c565b91505092959194509250565b81516001600160a01b031681526020808301516001600160401b03169082015260408083015115159082015260608101610b5c565b600080604083850312156132e957600080fd5b6132f283612d07565b915061330060208401612d07565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561333257613332613309565b500190565b600081600019048311821515161561335157613351613309565b500290565b600181811c9082168061336a57607f821691505b60208210810361338a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601260045260246000fd5b6000826133b5576133b5613390565b500490565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60008351613417818460208801612c9c565b83519083019061342b818360208801612c9c565b64173539b7b760d91b9101908152600501949350505050565b60006020828403121561345657600080fd5b81516110d081612dab565b60006001820161347357613473613309565b5060010190565b60008282101561348c5761348c613309565b500390565b6000826134a0576134a0613390565b500690565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906134d890830184612cc8565b9695505050505050565b6000602082840312156134f457600080fd5b81516110d081612c5056fea2646970667358221220cb22fbdbfca1b59d20997d3125261da6743fc511828b830f8a001cc9f874a4db64736f6c634300080d0033

Deployed Bytecode

0x6080604052600436106103a25760003560e01c806370a08231116101e7578063a22cb4651161010d578063d5b3621b116100a0578063f1d5f5171161006f578063f1d5f51714610a9c578063f2fde38b14610abc578063f4a0a52814610adc578063fc5384d814610afc57600080fd5b8063d5b3621b14610a1d578063e0a8085314610a3d578063e52c837514610a5d578063e985e9c514610a7c57600080fd5b8063c87b56dd116100dc578063c87b56dd1461099b578063d3738fc8146109bb578063d41f4dd2146109e8578063d4a6762314610a0857600080fd5b8063a22cb4651461091b578063b0ea7dcf1461093b578063b88d4fde1461094e578063c23dc68f1461096e57600080fd5b80638a69a5d9116101855780639418163a116101545780639418163a146108aa57806395d89b41146108c457806399a2557a146108d9578063a1cb31b7146108f957600080fd5b80638a69a5d91461084b5780638bc59ebc146108605780638da5cb5b1461087657806392ec8a471461089457600080fd5b8063750521f5116101c1578063750521f5146107be5780637cb64759146107de5780637e567acd146107fe5780638462151c1461081e57600080fd5b806370a0823114610773578063715018a61461079357806372836f35146107a857600080fd5b806341f43434116102cc5780635bbb21771161026a57806363553e7c1161023957806363553e7c146106fd578063653a819e146107135780636ebeac85146107335780636f8b44b01461075357600080fd5b80635bbb2177146106705780635c85974f1461069d578063627804af146106bd5780636352211e146106dd57600080fd5b806345bc00df116102a657806345bc00df146105fa5780634656750a1461061a5780634fdd43cb146106305780635a23dd991461065057600080fd5b806341f434341461059857806342676e6c146105ba57806342842e0e146105da57600080fd5b80630e2351e2116103445780632a55205a116103135780632a55205a1461050e5780632fc37ab21461054d5780633ccfd60b146105635780633d2722941461057857600080fd5b80630e2351e2146104a557806318160ddd146104bb57806322f4596f146104d857806323b872dd146104ee57600080fd5b806306fdde031161038057806306fdde0314610415578063081812fc14610437578063095ea7b31461046f5780630c6767341461048f57600080fd5b806301ffc9a7146103a75780630215bc7d146103dc5780630387da42146103f1575b600080fd5b3480156103b357600080fd5b506103c76103c2366004612c66565b610b1c565b60405190151581526020015b60405180910390f35b6103ef6103ea366004612c83565b610b62565b005b3480156103fd57600080fd5b50610407600f5481565b6040519081526020016103d3565b34801561042157600080fd5b5061042a610ce4565b6040516103d39190612cf4565b34801561044357600080fd5b50610457610452366004612c83565b610d76565b6040516001600160a01b0390911681526020016103d3565b34801561047b57600080fd5b506103ef61048a366004612d23565b610dba565b34801561049b57600080fd5b50610407600c5481565b3480156104b157600080fd5b5061040760115481565b3480156104c757600080fd5b506003546002540360001901610407565b3480156104e457600080fd5b5061040760135481565b3480156104fa57600080fd5b506103ef610509366004612d4d565b610dd3565b34801561051a57600080fd5b5061052e610529366004612d89565b610dfe565b604080516001600160a01b0390931683526020830191909152016103d3565b34801561055957600080fd5b5061040760185481565b34801561056f57600080fd5b506103ef610eac565b34801561058457600080fd5b506103ef610593366004612c83565b610f47565b3480156105a457600080fd5b506104576daaeb6d7670e522a718067333cd4e81565b3480156105c657600080fd5b506103ef6105d5366004612c83565b610f76565b3480156105e657600080fd5b506103ef6105f5366004612d4d565b610fa5565b34801561060657600080fd5b506103ef610615366004612db9565b610fca565b34801561062657600080fd5b5061040760145481565b34801561063c57600080fd5b506103ef61064b366004612e73565b61100e565b34801561065c57600080fd5b506103c761066b366004612eff565b61104f565b34801561067c57600080fd5b5061069061068b366004612f51565b6110d7565b6040516103d39190612ff6565b3480156106a957600080fd5b506103ef6106b8366004612c83565b61119d565b3480156106c957600080fd5b506103ef6106d8366004612d23565b6111cc565b3480156106e957600080fd5b506104576106f8366004612c83565b611233565b34801561070957600080fd5b5061040760105481565b34801561071f57600080fd5b506103ef61072e366004613060565b611245565b34801561073f57600080fd5b506015546103c79062010000900460ff1681565b34801561075f57600080fd5b506103ef61076e366004612c83565b61128d565b34801561077f57600080fd5b5061040761078e366004613089565b6112bc565b34801561079f57600080fd5b506103ef61130a565b3480156107b457600080fd5b5061040760125481565b3480156107ca57600080fd5b506103ef6107d9366004612e73565b611340565b3480156107ea57600080fd5b506103ef6107f9366004612c83565b61137d565b34801561080a57600080fd5b506103ef610819366004612db9565b6113ac565b34801561082a57600080fd5b5061083e610839366004613089565b6113e9565b6040516103d391906130a4565b34801561085757600080fd5b5061042a61152e565b34801561086c57600080fd5b50610407600e5481565b34801561088257600080fd5b50600a546001600160a01b0316610457565b3480156108a057600080fd5b50610407600d5481565b3480156108b657600080fd5b506015546103c79060ff1681565b3480156108d057600080fd5b5061042a6115bc565b3480156108e557600080fd5b5061083e6108f43660046130dc565b6115cb565b34801561090557600080fd5b5061090e61178c565b6040516103d3919061310f565b34801561092757600080fd5b506103ef6109363660046131ae565b611892565b6103ef6109493660046131e5565b6118a6565b34801561095a57600080fd5b506103ef610969366004613226565b6119ff565b34801561097a57600080fd5b5061098e610989366004612c83565b611a2c565b6040516103d391906132a1565b3480156109a757600080fd5b5061042a6109b6366004612c83565b611ae6565b3480156109c757600080fd5b506104076109d6366004613089565b60196020526000908152604090205481565b3480156109f457600080fd5b506103ef610a03366004612c83565b611c76565b348015610a1457600080fd5b5061042a611ca5565b348015610a2957600080fd5b506103ef610a38366004612c83565b611cb2565b348015610a4957600080fd5b506103ef610a58366004612db9565b611ce1565b348015610a6957600080fd5b506015546103c790610100900460ff1681565b348015610a8857600080fd5b506103c7610a973660046132d6565b611d27565b348015610aa857600080fd5b506103ef610ab7366004612c83565b611d55565b348015610ac857600080fd5b506103ef610ad7366004613089565b611d84565b348015610ae857600080fd5b506103ef610af7366004612c83565b611e1c565b348015610b0857600080fd5b506103ef610b17366004612c83565b611e4b565b60006001600160e01b0319821663152a902d60e11b1480610b4d57506001600160e01b031982166380ac58cd60e01b145b80610b5c5750610b5c82611e7a565b92915050565b323314610b82576040516367f91f7760e11b815260040160405180910390fd5b60155460ff16610ba557604051634c45182560e11b815260040160405180910390fd5b601254421015610bc857604051634c45182560e11b815260040160405180910390fd5b60135460025460001901610bdc908361331f565b1115610bfb57604051630af76cd360e31b815260040160405180910390fd5b601054811115610c1e5760405163552d9c8360e01b815260040160405180910390fd5b6000600f5482610c2e9190613337565b33600090815260196020526040902054601154919250908110610c64576040516305c6e3a560e21b815260040160405180910390fd5b601154610c71848361331f565b1115610c90576040516305c6e3a560e21b815260040160405180910390fd5b81341015610cb15760405163272c430f60e21b815260040160405180910390fd5b610cbb3384611eba565b3360009081526019602052604081208054859290610cda90849061331f565b9091555050505050565b606060048054610cf390613356565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1f90613356565b8015610d6c5780601f10610d4157610100808354040283529160200191610d6c565b820191906000526020600020905b815481529060010190602001808311610d4f57829003601f168201915b5050505050905090565b6000610d8182611ed4565b610d9e576040516333d1c03960e21b815260040160405180910390fd5b506000908152600860205260409020546001600160a01b031690565b81610dc481611f0d565b610dce8383611fc6565b505050565b826001600160a01b0381163314610ded57610ded33611f0d565b610df884848461204e565b50505050565b60008281526001602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610e735750604080518082019091526000546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610e92906001600160601b031687613337565b610e9c91906133a6565b91519350909150505b9250929050565b600a546001600160a01b03163314610edf5760405162461bcd60e51b8152600401610ed6906133ba565b60405180910390fd5b6002600b5403610f315760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ed6565b6002600b55610f403347612059565b6001600b55565b600a546001600160a01b03163314610f715760405162461bcd60e51b8152600401610ed6906133ba565b600c55565b600a546001600160a01b03163314610fa05760405162461bcd60e51b8152600401610ed6906133ba565b600e55565b826001600160a01b0381163314610fbf57610fbf33611f0d565b610df8848484612172565b600a546001600160a01b03163314610ff45760405162461bcd60e51b8152600401610ed6906133ba565b601580549115156101000261ff0019909216919091179055565b600a546001600160a01b031633146110385760405162461bcd60e51b8152600401610ed6906133ba565b805161104b906017906020840190612bb7565b5050565b6040516bffffffffffffffffffffffff19606085901b16602082015260009081906034016040516020818303038152906040528051906020012090506110cc84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050601854915084905061218d565b9150505b9392505050565b80516060906000816001600160401b038111156110f6576110f6612dd6565b60405190808252806020026020018201604052801561114157816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816111145790505b50905060005b82811461119557611170858281518110611163576111636133ef565b6020026020010151611a2c565b828281518110611182576111826133ef565b6020908102919091010152600101611147565b509392505050565b600a546001600160a01b031633146111c75760405162461bcd60e51b8152600401610ed6906133ba565b601055565b600a546001600160a01b031633146111f65760405162461bcd60e51b8152600401610ed6906133ba565b6013546002546000190161120a908361331f565b111561122957604051630af76cd360e31b815260040160405180910390fd5b61104b8282611eba565b600061123e826121a3565b5192915050565b600a546001600160a01b0316331461126f5760405162461bcd60e51b8152600401610ed6906133ba565b61128a611284600a546001600160a01b031690565b826122ca565b50565b600a546001600160a01b031633146112b75760405162461bcd60e51b8152600401610ed6906133ba565b601355565b60006001600160a01b0382166112e5576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600760205260409020546001600160401b031690565b600a546001600160a01b031633146113345760405162461bcd60e51b8152600401610ed6906133ba565b61133e60006123c7565b565b600a546001600160a01b0316331461136a5760405162461bcd60e51b8152600401610ed6906133ba565b805161104b906016906020840190612bb7565b600a546001600160a01b031633146113a75760405162461bcd60e51b8152600401610ed6906133ba565b601855565b600a546001600160a01b031633146113d65760405162461bcd60e51b8152600401610ed6906133ba565b6015805460ff1916911515919091179055565b606060008060006113f9856112bc565b90506000816001600160401b0381111561141557611415612dd6565b60405190808252806020026020018201604052801561143e578160200160208202803683370190505b509050611464604080516060810182526000808252602082018190529181019190915290565b60015b83861461152257600081815260066020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161515918101829052925061151a5781516001600160a01b0316156114db57815194505b876001600160a01b0316856001600160a01b03160361151a578083878060010198508151811061150d5761150d6133ef565b6020026020010181815250505b600101611467565b50909695505050505050565b6017805461153b90613356565b80601f016020809104026020016040519081016040528092919081815260200182805461156790613356565b80156115b45780601f10611589576101008083540402835291602001916115b4565b820191906000526020600020905b81548152906001019060200180831161159757829003601f168201915b505050505081565b606060058054610cf390613356565b60608183106115ed57604051631960ccad60e11b815260040160405180910390fd5b600254600090600185101561160157600194505b8084111561160d578093505b6000611618876112bc565b9050848610156116375785850381811015611631578091505b5061163b565b5060005b6000816001600160401b0381111561165557611655612dd6565b60405190808252806020026020018201604052801561167e578160200160208202803683370190505b509050816000036116945793506110d092505050565b600061169f88611a2c565b9050600081604001516116b0575080515b885b8881141580156116c25750848714155b1561177b57600081815260066020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff16151591810182905293506117735782516001600160a01b03161561173457825191505b8a6001600160a01b0316826001600160a01b0316036117735780848880600101995081518110611766576117666133ef565b6020026020010181815250505b6001016116b2565b505050928352509095945050505050565b6117fd604051806101a00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581526020016000151581526020016000151581526020016000815260200160008152602001600081525090565b604051806101a00160405280600c548152602001600d548152602001600f5481526020016010548152602001601154815260200160135481526020016118466002546000190190565b815260155460ff6201000082048116151560208401528082161515604084015261010090910416151560608201526012546080820152600e5460a082015260145460c090910152919050565b8161189c81611f0d565b610dce8383612419565b3233146118c6576040516367f91f7760e11b815260040160405180910390fd5b601554610100900460ff166118ee57604051638380787360e01b815260040160405180910390fd5b600e5442101561191157604051638380787360e01b815260040160405180910390fd5b601454600e54611921919061331f565b42111561194157604051631a3b6d8960e21b815260040160405180910390fd5b60135460025460001901600d54611958919061331f565b111561197757604051630af76cd360e31b815260040160405180910390fd5b61198233838361104f565b61199f5760405163b14a633d60e01b815260040160405180910390fd5b33600090815260196020526040902054600d5481106119d1576040516305c6e3a560e21b815260040160405180910390fd5b6119dd33600d54611eba565b600d543360009081526019602052604081208054909190610cda90849061331f565b836001600160a01b0381163314611a1957611a1933611f0d565b611a25858585856124ae565b5050505050565b60408051606080820183526000808352602080840182905283850182905284519283018552818352820181905292810192909252906001831080611a7257506002548310155b15611a7d5792915050565b50600082815260066020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161580159282019290925290611add5792915050565b6110d0836121a3565b6060611af182611ed4565b611b0e57604051630a14c4b560e41b815260040160405180910390fd5b60155462010000900460ff161515600003611bb55760178054611b3090613356565b80601f0160208091040260200160405190810160405280929190818152602001828054611b5c90613356565b8015611ba95780601f10611b7e57610100808354040283529160200191611ba9565b820191906000526020600020905b815481529060010190602001808311611b8c57829003601f168201915b50505050509050919050565b600060168054611bc490613356565b80601f0160208091040260200160405190810160405280929190818152602001828054611bf090613356565b8015611c3d5780601f10611c1257610100808354040283529160200191611c3d565b820191906000526020600020905b815481529060010190602001808311611c2057829003601f168201915b5050505050905080611c4e846124f9565b604051602001611c5f929190613405565b604051602081830303815290604052915050919050565b600a546001600160a01b03163314611ca05760405162461bcd60e51b8152600401610ed6906133ba565b600d55565b6016805461153b90613356565b600a546001600160a01b03163314611cdc5760405162461bcd60e51b8152600401610ed6906133ba565b601255565b600a546001600160a01b03163314611d0b5760405162461bcd60e51b8152600401610ed6906133ba565b60158054911515620100000262ff000019909216919091179055565b6001600160a01b03918216600090815260096020908152604080832093909416825291909152205460ff1690565b600a546001600160a01b03163314611d7f5760405162461bcd60e51b8152600401610ed6906133ba565b601155565b600a546001600160a01b03163314611dae5760405162461bcd60e51b8152600401610ed6906133ba565b6001600160a01b038116611e135760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ed6565b61128a816123c7565b600a546001600160a01b03163314611e465760405162461bcd60e51b8152600401610ed6906133ba565b600f55565b600a546001600160a01b03163314611e755760405162461bcd60e51b8152600401610ed6906133ba565b601455565b60006001600160e01b031982166380ac58cd60e01b1480611eab57506001600160e01b03198216635b5e139f60e01b145b80610b5c5750610b5c82612601565b61104b828260405180602001604052806000815250612636565b600081600111158015611ee8575060025482105b8015610b5c575050600090815260066020526040902054600160e01b900460ff161590565b6daaeb6d7670e522a718067333cd4e3b1561128a57604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa158015611f7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9e9190613444565b61128a57604051633b79c77360e21b81526001600160a01b0382166004820152602401610ed6565b6000611fd182611233565b9050806001600160a01b0316836001600160a01b0316036120055760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b0382161480159061202557506120238133611d27565b155b15612043576040516367d9dca160e11b815260040160405180910390fd5b610dce838383612643565b610dce83838361269f565b804710156120a95760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610ed6565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146120f6576040519150601f19603f3d011682016040523d82523d6000602084013e6120fb565b606091505b5050905080610dce5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610ed6565b610dce838383604051806020016040528060008152506119ff565b60008261219a858461288a565b14949350505050565b604080516060810182526000808252602082018190529181019190915281806001111580156121d3575060025481105b156122b157600081815260066020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161515918101829052906122af5780516001600160a01b031615612246579392505050565b5060001901600081815260066020908152604091829020825160608101845290546001600160a01b038116808352600160a01b82046001600160401b031693830193909352600160e01b900460ff16151592810192909252156122aa579392505050565b612246565b505b604051636f96cda160e11b815260040160405180910390fd5b6127106001600160601b03821611156123385760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401610ed6565b6001600160a01b03821661238e5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610ed6565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600055565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b336001600160a01b038316036124425760405163b06307db60e01b815260040160405180910390fd5b3360008181526009602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6124b984848461269f565b6001600160a01b0383163b151580156124db57506124d9848484846128cf565b155b15610df8576040516368d2bf6b60e11b815260040160405180910390fd5b6060816000036125205750506040805180820190915260018152600360fc1b602082015290565b8160005b811561254a578061253481613461565b91506125439050600a836133a6565b9150612524565b6000816001600160401b0381111561256457612564612dd6565b6040519080825280601f01601f19166020018201604052801561258e576020820181803683370190505b5090505b84156125f9576125a360018361347a565b91506125b0600a86613491565b6125bb90603061331f565b60f81b8183815181106125d0576125d06133ef565b60200101906001600160f81b031916908160001a9053506125f2600a866133a6565b9450612592565b949350505050565b60006001600160e01b0319821663152a902d60e11b1480610b5c57506301ffc9a760e01b6001600160e01b0319831614610b5c565b610dce83838360016129ba565b60008281526008602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b60006126aa826121a3565b9050836001600160a01b031681600001516001600160a01b0316146126e15760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b03861614806126ff57506126ff8533611d27565b8061271a57503361270f84610d76565b6001600160a01b0316145b90508061273a57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03841661276157604051633a954ecd60e21b815260040160405180910390fd5b61276d60008487612643565b6001600160a01b038581166000908152600760209081526040808320805467ffffffffffffffff198082166001600160401b0392831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600690945282852080546001600160e01b031916909417600160a01b4290921691909102178355870180845292208054919390911661284157600254821461284157805460208601516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038a16171781555b50505082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611a25565b600081815b8451811015611195576128bb828683815181106128ae576128ae6133ef565b6020026020010151612b8b565b9150806128c781613461565b91505061288f565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906129049033908990889088906004016134a5565b6020604051808303816000875af192505050801561293f575060408051601f3d908101601f1916820190925261293c918101906134e2565b60015b61299d573d80801561296d576040519150601f19603f3d011682016040523d82523d6000602084013e612972565b606091505b508051600003612995576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b6002546001600160a01b0385166129e357604051622e076360e81b815260040160405180910390fd5b83600003612a045760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038516600081815260076020908152604080832080546fffffffffffffffffffffffffffffffff1981166001600160401b038083168c0181169182176801000000000000000067ffffffffffffffff1990941690921783900481168c01811690920217909155858452600690925290912080546001600160e01b031916909217600160a01b429092169190910217905580808501838015612ab557506001600160a01b0387163b15155b15612b3d575b60405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4612b0660008884806001019550886128cf565b612b23576040516368d2bf6b60e11b815260040160405180910390fd5b808203612abb578260025414612b3857600080fd5b612b82565b5b6040516001830192906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4808203612b3e575b50600255611a25565b6000818310612ba75760008281526020849052604090206110d0565b5060009182526020526040902090565b828054612bc390613356565b90600052602060002090601f016020900481019282612be55760008555612c2b565b82601f10612bfe57805160ff1916838001178555612c2b565b82800160010185558215612c2b579182015b82811115612c2b578251825591602001919060010190612c10565b50612c37929150612c3b565b5090565b5b80821115612c375760008155600101612c3c565b6001600160e01b03198116811461128a57600080fd5b600060208284031215612c7857600080fd5b81356110d081612c50565b600060208284031215612c9557600080fd5b5035919050565b60005b83811015612cb7578181015183820152602001612c9f565b83811115610df85750506000910152565b60008151808452612ce0816020860160208601612c9c565b601f01601f19169290920160200192915050565b6020815260006110d06020830184612cc8565b80356001600160a01b0381168114612d1e57600080fd5b919050565b60008060408385031215612d3657600080fd5b612d3f83612d07565b946020939093013593505050565b600080600060608486031215612d6257600080fd5b612d6b84612d07565b9250612d7960208501612d07565b9150604084013590509250925092565b60008060408385031215612d9c57600080fd5b50508035926020909101359150565b801515811461128a57600080fd5b600060208284031215612dcb57600080fd5b81356110d081612dab565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612e1457612e14612dd6565b604052919050565b60006001600160401b03831115612e3557612e35612dd6565b612e48601f8401601f1916602001612dec565b9050828152838383011115612e5c57600080fd5b828260208301376000602084830101529392505050565b600060208284031215612e8557600080fd5b81356001600160401b03811115612e9b57600080fd5b8201601f81018413612eac57600080fd5b6125f984823560208401612e1c565b60008083601f840112612ecd57600080fd5b5081356001600160401b03811115612ee457600080fd5b6020830191508360208260051b8501011115610ea557600080fd5b600080600060408486031215612f1457600080fd5b612f1d84612d07565b925060208401356001600160401b03811115612f3857600080fd5b612f4486828701612ebb565b9497909650939450505050565b60006020808385031215612f6457600080fd5b82356001600160401b0380821115612f7b57600080fd5b818501915085601f830112612f8f57600080fd5b813581811115612fa157612fa1612dd6565b8060051b9150612fb2848301612dec565b8181529183018401918481019088841115612fcc57600080fd5b938501935b83851015612fea57843582529385019390850190612fd1565b98975050505050505050565b6020808252825182820181905260009190848201906040850190845b818110156115225761304d83855180516001600160a01b031682526020808201516001600160401b0316908301526040908101511515910152565b9284019260609290920191600101613012565b60006020828403121561307257600080fd5b81356001600160601b03811681146110d057600080fd5b60006020828403121561309b57600080fd5b6110d082612d07565b6020808252825182820181905260009190848201906040850190845b81811015611522578351835292840192918401916001016130c0565b6000806000606084860312156130f157600080fd5b6130fa84612d07565b95602085013595506040909401359392505050565b60006101a082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015161316b60e084018215159052565b5061010083810151151590830152610120808401511515908301526101408084015190830152610160808401519083015261018092830151929091019190915290565b600080604083850312156131c157600080fd5b6131ca83612d07565b915060208301356131da81612dab565b809150509250929050565b600080602083850312156131f857600080fd5b82356001600160401b0381111561320e57600080fd5b61321a85828601612ebb565b90969095509350505050565b6000806000806080858703121561323c57600080fd5b61324585612d07565b935061325360208601612d07565b92506040850135915060608501356001600160401b0381111561327557600080fd5b8501601f8101871361328657600080fd5b61329587823560208401612e1c565b91505092959194509250565b81516001600160a01b031681526020808301516001600160401b03169082015260408083015115159082015260608101610b5c565b600080604083850312156132e957600080fd5b6132f283612d07565b915061330060208401612d07565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561333257613332613309565b500190565b600081600019048311821515161561335157613351613309565b500290565b600181811c9082168061336a57607f821691505b60208210810361338a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601260045260246000fd5b6000826133b5576133b5613390565b500490565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60008351613417818460208801612c9c565b83519083019061342b818360208801612c9c565b64173539b7b760d91b9101908152600501949350505050565b60006020828403121561345657600080fd5b81516110d081612dab565b60006001820161347357613473613309565b5060010190565b60008282101561348c5761348c613309565b500390565b6000826134a0576134a0613390565b500690565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906134d890830184612cc8565b9695505050505050565b6000602082840312156134f457600080fd5b81516110d081612c5056fea2646970667358221220cb22fbdbfca1b59d20997d3125261da6743fc511828b830f8a001cc9f874a4db64736f6c634300080d0033

Deployed Bytecode Sourcemap

646:8030:18:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7370:299;;;;;;;;;;-1:-1:-1;7370:299:18;;;;;:::i;:::-;;:::i;:::-;;;661:14:20;;654:22;636:41;;624:2;609:18;7370:299:18;;;;;;;;2502:884;;;;;;:::i;:::-;;:::i;:::-;;1036:35;;;;;;;;;;;;;;;;;;;1019:25:20;;;1007:2;992:18;1036:35:18;873:177:20;7550:100:6;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;9061:204::-;;;;;;;;;;-1:-1:-1;9061:204:6;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1970:32:20;;;1952:51;;1940:2;1925:18;9061:204:6;1806:203:20;7980:148:18;;;;;;;;;;-1:-1:-1;7980:148:18;;;;;:::i;:::-;;:::i;912:37::-;;;;;;;;;;;;;;;;1113:32;;;;;;;;;;;;;;;;3686:303:6;;;;;;;;;;-1:-1:-1;3940:12:6;;3924:13;;:28;-1:-1:-1;;3924:46:6;3686:303;;1190:33:18;;;;;;;;;;;;;;;;8133:154;;;;;;;;;;-1:-1:-1;8133:154:18;;;;;:::i;:::-;;:::i;1674:442:5:-;;;;;;;;;;-1:-1:-1;1674:442:5;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;3229:32:20;;;3211:51;;3293:2;3278:18;;3271:34;;;;3184:18;1674:442:5;3037:274:20;1475:26:18;;;;;;;;;;;;;;;;7680:122;;;;;;;;;;;;;:::i;5704:107::-;;;;;;;;;;-1:-1:-1;5704:107:18;;;;;:::i;:::-;;:::i;722:143:15:-;;;;;;;;;;;;822:42;722:143;;5445:123:18;;;;;;;;;;-1:-1:-1;5445:123:18;;;;;:::i;:::-;;:::i;8292:162::-;;;;;;;;;;-1:-1:-1;8292:162:18;;;;;:::i;:::-;;:::i;6484:98::-;;;;;;;;;;-1:-1:-1;6484:98:18;;;;;:::i;:::-;;:::i;1236:39::-;;;;;;;;;;;;;;;;6697:137;;;;;;;;;;-1:-1:-1;6697:137:18;;;;;:::i;:::-;;:::i;4725:227::-;;;;;;;;;;-1:-1:-1;4725:227:18;;;;;:::i;:::-;;:::i;1485:459:7:-;;;;;;;;;;-1:-1:-1;1485:459:7;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;5819:91:18:-;;;;;;;;;;-1:-1:-1;5819:91:18;;;;;:::i;:::-;;:::i;3398:186::-;;;;;;;;;;-1:-1:-1;3398:186:18;;;;;:::i;:::-;;:::i;7358:125:6:-;;;;;;;;;;-1:-1:-1;7358:125:6;;;;;:::i;:::-;;:::i;1078:28:18:-;;;;;;;;;;;;;;;;6846:125;;;;;;;;;;-1:-1:-1;6846:125:18;;;;;:::i;:::-;;:::i;1362:29::-;;;;;;;;;;-1:-1:-1;1362:29:18;;;;;;;;;;;6149:99;;;;;;;;;;-1:-1:-1;6149:99:18;;;;;:::i;:::-;;:::i;4806:206:6:-;;;;;;;;;;-1:-1:-1;4806:206:6;;;;;:::i;:::-;;:::i;1714:103:16:-;;;;;;;;;;;;;:::i;1152:29:18:-;;;;;;;;;;;;;;;;6590:99;;;;;;;;;;-1:-1:-1;6590:99:18;;;;;:::i;:::-;;:::i;4964:105::-;;;;;;;;;;-1:-1:-1;4964:105:18;;;;;:::i;:::-;;:::i;6358:114::-;;;;;;;;;;-1:-1:-1;6358:114:18;;;;;:::i;:::-;;:::i;5281:882:7:-;;;;;;;;;;-1:-1:-1;5281:882:7;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1436:32:18:-;;;;;;;;;;;;;:::i;996:31::-;;;;;;;;;;;;;;;;1063:87:16;;;;;;;;;;-1:-1:-1;1136:6:16;;-1:-1:-1;;;;;1136:6:16;1063:87;;956:33:18;;;;;;;;;;;;;;;;1284:34;;;;;;;;;;-1:-1:-1;1284:34:18;;;;;;;;7719:104:6;;;;;;;;;;;;;:::i;2334:2498:7:-;;;;;;;;;;-1:-1:-1;2334:2498:7;;;;;:::i;:::-;;:::i;4008:709:18:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;7808:167::-;;;;;;;;;;-1:-1:-1;7808:167:18;;;;;:::i;:::-;;:::i;1684:810::-;;;;;;:::i;:::-;;:::i;8459:210::-;;;;;;;;;;-1:-1:-1;8459:210:18;;;;;:::i;:::-;;:::i;917:409:7:-;;;;;;;;;;-1:-1:-1;917:409:7;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;6979:383:18:-;;;;;;;;;;-1:-1:-1;6979:383:18;;;;;:::i;:::-;;:::i;1514:48::-;;;;;;;;;;-1:-1:-1;1514:48:18;;;;;:::i;:::-;;;;;;;;;;;;;;5576:115;;;;;;;;;;-1:-1:-1;5576:115:18;;;;;:::i;:::-;;:::i;1398:31::-;;;;;;;;;;;;;:::i;5318:115::-;;;;;;;;;;-1:-1:-1;5318:115:18;;;;;:::i;:::-;;:::i;6257:92::-;;;;;;;;;;-1:-1:-1;6257:92:18;;;;;:::i;:::-;;:::i;1325:30::-;;;;;;;;;;-1:-1:-1;1325:30:18;;;;;;;;;;;9695:164:6;;;;;;;;;;-1:-1:-1;9695:164:6;;;;;:::i;:::-;;:::i;5922:107:18:-;;;;;;;;;;-1:-1:-1;5922:107:18;;;;;:::i;:::-;;:::i;1972:201:16:-;;;;;;;;;;-1:-1:-1;1972:201:16;;;;;:::i;:::-;;:::i;6038:99:18:-;;;;;;;;;;-1:-1:-1;6038:99:18;;;;;:::i;:::-;;:::i;5187:123::-;;;;;;;;;;-1:-1:-1;5187:123:18;;;;;:::i;:::-;;:::i;7370:299::-;7473:4;-1:-1:-1;;;;;;7510:41:18;;-1:-1:-1;;;7510:41:18;;:98;;-1:-1:-1;;;;;;;7568:40:18;;-1:-1:-1;;;7568:40:18;7510:98;:151;;;;7625:36;7649:11;7625:23;:36::i;:::-;7490:171;7370:299;-1:-1:-1;;7370:299:18:o;2502:884::-;2569:9;2582:10;2569:23;2565:61;;2601:25;;-1:-1:-1;;;2601:25:18;;;;;;;;;;;2565:61;2642:14;;;;2637:54;;2665:26;;-1:-1:-1;;;2665:26:18;;;;;;;;;;;2637:54;2724:14;;2706:15;:32;2702:71;;;2747:26;;-1:-1:-1;;;2747:26:18;;;;;;;;;;;2702:71;2814:10;;4315:13:6;;-1:-1:-1;;4315:31:6;2788:23:18;;:6;:23;:::i;:::-;:36;2784:71;;;2833:22;;-1:-1:-1;;;2833:22:18;;;;;;;;;;;2784:71;2879:8;;2870:6;:17;2866:59;;;2896:29;;-1:-1:-1;;;2896:29:18;;;;;;;;;;;2866:59;2946:21;2979:10;;2970:6;:19;;;;:::i;:::-;3034:10;3000:18;3021:24;;;:12;:24;;;;;;3074:12;;2946:43;;-1:-1:-1;3021:24:18;3060:26;;3056:63;;3095:24;;-1:-1:-1;;;3095:24:18;;;;;;;;;;;3056:63;3156:12;;3134:19;3147:6;3134:10;:19;:::i;:::-;:34;3130:71;;;3177:24;;-1:-1:-1;;;3177:24:18;;;;;;;;;;;3130:71;3228:13;3216:9;:25;3212:61;;;3250:23;;-1:-1:-1;;;3250:23:18;;;;;;;;;;;3212:61;3294:29;3304:10;3316:6;3294:9;:29::i;:::-;3347:10;3334:24;;;;:12;:24;;;;;:34;;3362:6;;3334:24;:34;;3362:6;;3334:34;:::i;:::-;;;;-1:-1:-1;;;;;2502:884:18:o;7550:100:6:-;7604:13;7637:5;7630:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7550:100;:::o;9061:204::-;9129:7;9154:16;9162:7;9154;:16::i;:::-;9149:64;;9179:34;;-1:-1:-1;;;9179:34:6;;;;;;;;;;;9149:64;-1:-1:-1;9233:24:6;;;;:15;:24;;;;;;-1:-1:-1;;;;;9233:24:6;;9061:204::o;7980:148:18:-;8076:8;2243:30:15;2264:8;2243:20;:30::i;:::-;8091:32:18::1;8105:8;8115:7;8091:13;:32::i;:::-;7980:148:::0;;;:::o;8133:154::-;8234:4;-1:-1:-1;;;;;2063:18:15;;2071:10;2063:18;2059:83;;2098:32;2119:10;2098:20;:32::i;:::-;8245:37:18::1;8264:4;8270:2;8274:7;8245:18;:37::i;:::-;8133:154:::0;;;;:::o;1674:442:5:-;1771:7;1829:27;;;:17;:27;;;;;;;;1800:56;;;;;;;;;-1:-1:-1;;;;;1800:56:5;;;;;-1:-1:-1;;;1800:56:5;;;-1:-1:-1;;;;;1800:56:5;;;;;;;;1771:7;;1869:92;;-1:-1:-1;1920:29:5;;;;;;;;;-1:-1:-1;1920:29:5;-1:-1:-1;;;;;1920:29:5;;;;-1:-1:-1;;;1920:29:5;;-1:-1:-1;;;;;1920:29:5;;;;;1869:92;2011:23;;;;1973:21;;2482:5;;1998:36;;-1:-1:-1;;;;;1998:36:5;:10;:36;:::i;:::-;1997:58;;;;:::i;:::-;2076:16;;;-1:-1:-1;1973:82:5;;-1:-1:-1;;1674:442:5;;;;;;:::o;7680:122:18:-;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;;;;;;;;;1778:1:17::1;2376:7;;:19:::0;2368:63:::1;;;::::0;-1:-1:-1;;;2368:63:17;;14744:2:20;2368:63:17::1;::::0;::::1;14726:21:20::0;14783:2;14763:18;;;14756:30;14822:33;14802:18;;;14795:61;14873:18;;2368:63:17::1;14542:355:20::0;2368:63:17::1;1778:1;2509:7;:18:::0;7742:52:18::2;7750:10;7772:21;7742:29;:52::i;:::-;1734:1:17::1;2688:7;:22:::0;7680:122:18:o;5704:107::-;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;5777:12:18::1;:26:::0;5704:107::o;5445:123::-;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;5526:16:18::1;:34:::0;5445:123::o;8292:162::-;8397:4;-1:-1:-1;;;;;2063:18:15;;2071:10;2063:18;2059:83;;2098:32;2119:10;2098:20;:32::i;:::-;8408:41:18::1;8431:4;8437:2;8441:7;8408:22;:41::i;6484:98::-:0;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;6552:10:18::1;:22:::0;;;::::1;;;;-1:-1:-1::0;;6552:22:18;;::::1;::::0;;;::::1;::::0;;6484:98::o;6697:137::-;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;6788:38:18;;::::1;::::0;:18:::1;::::0;:38:::1;::::0;::::1;::::0;::::1;:::i;:::-;;6697:137:::0;:::o;4725:227::-;4855:22;;-1:-1:-1;;15051:2:20;15047:15;;;15043:53;4855:22:18;;;15031:66:20;4813:4:18;;;;15113:12:20;;4855:22:18;;;;;;;;;;;;4845:33;;;;;;4830:48;;4896;4915:9;;4896:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4926:11:18;;;-1:-1:-1;4939:4:18;;-1:-1:-1;4896:18:18;:48::i;:::-;4889:55;;;4725:227;;;;;;:::o;1485:459:7:-;1651:15;;1565:23;;1626:22;1651:15;-1:-1:-1;;;;;1718:36:7;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;1718:36:7;;-1:-1:-1;;1718:36:7;;;;;;;;;;;;1681:73;;1774:9;1769:125;1790:14;1785:1;:19;1769:125;;1846:32;1866:8;1875:1;1866:11;;;;;;;;:::i;:::-;;;;;;;1846:19;:32::i;:::-;1830:10;1841:1;1830:13;;;;;;;;:::i;:::-;;;;;;;;;;:48;1806:3;;1769:125;;;-1:-1:-1;1915:10:7;1485:459;-1:-1:-1;;;1485:459:7:o;5819:91:18:-;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;5884:8:18::1;:18:::0;5819:91::o;3398:186::-;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;3503:10:18::1;::::0;4315:13:6;;-1:-1:-1;;4315:31:6;3477:23:18::1;::::0;:6;:23:::1;:::i;:::-;:36;3473:71;;;3522:22;;-1:-1:-1::0;;;3522:22:18::1;;;;;;;;;;;3473:71;3555:21;3565:2;3569:6;3555:9;:21::i;7358:125:6:-:0;7422:7;7449:21;7462:7;7449:12;:21::i;:::-;:26;;7358:125;-1:-1:-1;;7358:125:6:o;6846::18:-;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;6922:41:18::1;6941:7;1136:6:16::0;;-1:-1:-1;;;;;1136:6:16;;1063:87;6941:7:18::1;6950:12;6922:18;:41::i;:::-;6846:125:::0;:::o;6149:99::-;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;6218:10:18::1;:22:::0;6149:99::o;4806:206:6:-;4870:7;-1:-1:-1;;;;;4894:19:6;;4890:60;;4922:28;;-1:-1:-1;;;4922:28:6;;;;;;;;;;;4890:60;-1:-1:-1;;;;;;4976:19:6;;;;;:12;:19;;;;;:27;-1:-1:-1;;;;;4976:27:6;;4806:206::o;1714:103:16:-;1136:6;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;1779:30:::1;1806:1;1779:18;:30::i;:::-;1714:103::o:0;6590:99:18:-;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;6663:18:18;;::::1;::::0;:12:::1;::::0;:18:::1;::::0;::::1;::::0;::::1;:::i;4964:105::-:0;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;5037:11:18::1;:24:::0;4964:105::o;6358:114::-;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;6434:14:18::1;:30:::0;;-1:-1:-1;;6434:30:18::1;::::0;::::1;;::::0;;;::::1;::::0;;6358:114::o;5281:882:7:-;5342:16;5396:19;5430:25;5470:22;5495:16;5505:5;5495:9;:16::i;:::-;5470:41;;5526:25;5568:14;-1:-1:-1;;;;;5554:29:7;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5554:29:7;;5526:57;;5598:31;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;5598:31:7;5169:1:18;5644:471:7;5693:14;5678:11;:29;5644:471;;5745:14;;;;:11;:14;;;;;;;;;5733:26;;;;;;;;;-1:-1:-1;;;;;5733:26:7;;;;-1:-1:-1;;;5733:26:7;;-1:-1:-1;;;;;5733:26:7;;;;;;;;-1:-1:-1;;;5733:26:7;;;;;;;;;;;;;;-1:-1:-1;5823:8:7;5778:73;5873:14;;-1:-1:-1;;;;;5873:28:7;;5869:111;;5946:14;;;-1:-1:-1;5869:111:7;6023:5;-1:-1:-1;;;;;6002:26:7;:17;-1:-1:-1;;;;;6002:26:7;;5998:102;;6079:1;6053:8;6062:13;;;;;;6053:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;5998:102;5709:3;;5644:471;;;-1:-1:-1;6136:8:7;;5281:882;-1:-1:-1;;;;;;5281:882:7:o;1436:32:18:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7719:104:6:-;7775:13;7808:7;7801:14;;;;;:::i;2334:2498:7:-;2460:16;2527:4;2518:5;:13;2514:45;;2540:19;;-1:-1:-1;;;2540:19:7;;;;;;;;;;;2514:45;2628:13;;2574:19;;5169:1:18;2719:5:7;:23;2715:87;;;5169:1:18;2763:23:7;;2715:87;2882:9;2875:4;:16;2871:73;;;2919:9;2912:16;;2871:73;2958:25;2986:16;2996:5;2986:9;:16::i;:::-;2958:44;;3180:4;3172:5;:12;3168:278;;;3227:12;;;3262:31;;;3258:111;;;3338:11;3318:31;;3258:111;3186:198;3168:278;;;-1:-1:-1;3429:1:7;3168:278;3460:25;3502:17;-1:-1:-1;;;;;3488:32:7;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3488:32:7;;3460:60;;3539:17;3560:1;3539:22;3535:78;;3589:8;-1:-1:-1;3582:15:7;;-1:-1:-1;;;3582:15:7;3535:78;3757:31;3791:26;3811:5;3791:19;:26::i;:::-;3757:60;;3832:25;4077:9;:16;;;4072:92;;-1:-1:-1;4134:14:7;;4072:92;4195:5;4178:477;4207:4;4202:1;:9;;:45;;;;;4230:17;4215:11;:32;;4202:45;4178:477;;;4285:14;;;;:11;:14;;;;;;;;;4273:26;;;;;;;;;-1:-1:-1;;;;;4273:26:7;;;;-1:-1:-1;;;4273:26:7;;-1:-1:-1;;;;;4273:26:7;;;;;;;;-1:-1:-1;;;4273:26:7;;;;;;;;;;;;;;-1:-1:-1;4363:8:7;4318:73;4413:14;;-1:-1:-1;;;;;4413:28:7;;4409:111;;4486:14;;;-1:-1:-1;4409:111:7;4563:5;-1:-1:-1;;;;;4542:26:7;:17;-1:-1:-1;;;;;4542:26:7;;4538:102;;4619:1;4593:8;4602:13;;;;;;4593:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;4538:102;4249:3;;4178:477;;;-1:-1:-1;;;4740:29:7;;;-1:-1:-1;4740:29:7;;2334:2498;-1:-1:-1;;;;;2334:2498:7:o;4008:709:18:-;4049:12;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4049:12:18;4094:615;;;;;;;;4132:12;;4094:615;;;;4178:14;;4094:615;;;;4222:10;;4094:615;;;;4260:8;;4094:615;;;;4300:12;;4094:615;;;;4342:10;;4094:615;;;;4392:22;4315:13:6;;-1:-1:-1;;4315:31:6;;4082:283;4392:22:18;4094:615;;4444:9;;;;;;;;4094:615;;;;;;4487:14;;;4094:615;;;;;;4444:9;4531:10;;;;4094:615;;;;;;4575:14;;4094:615;;;;4625:16;;4094:615;;;;4677:16;;4094:615;;;;;4074:635;4008:709;-1:-1:-1;4008:709:18:o;7808:167::-;7912:8;2243:30:15;2264:8;2243:20;:30::i;:::-;7927:43:18::1;7951:8;7961;7927:23;:43::i;1684:810::-:0;1762:9;1775:10;1762:23;1758:61;;1794:25;;-1:-1:-1;;;1794:25:18;;;;;;;;;;;1758:61;1835:10;;;;;;;1830:47;;1854:23;;-1:-1:-1;;;1854:23:18;;;;;;;;;;;1830:47;1910:16;;1892:15;:34;1888:70;;;1935:23;;-1:-1:-1;;;1935:23:18;;;;;;;;;;;1888:70;2010:16;;1991;;:35;;;;:::i;:::-;1973:15;:53;1969:90;;;2036:23;;-1:-1:-1;;;2036:23:18;;;;;;;;;;;1969:90;2108:10;;4315:13:6;;-1:-1:-1;;4315:31:6;2074:14:18;;:31;;;;:::i;:::-;:44;2070:79;;;2127:22;;-1:-1:-1;;;2127:22:18;;;;;;;;;;;2070:79;2165:36;2179:10;2191:9;;2165:13;:36::i;:::-;2160:71;;2210:21;;-1:-1:-1;;;2210:21:18;;;;;;;;;;;2160:71;2278:10;2244:18;2265:24;;;:12;:24;;;;;;2318:14;;2304:28;;2300:65;;2341:24;;-1:-1:-1;;;2341:24:18;;;;;;;;;;;2300:65;2386:37;2396:10;2408:14;;2386:9;:37::i;:::-;2462:14;;2447:10;2434:24;;;;:12;:24;;;;;:42;;:24;;;:42;;2462:14;;2434:42;:::i;8459:210::-;8604:4;-1:-1:-1;;;;;2063:18:15;;2071:10;2063:18;2059:83;;2098:32;2119:10;2098:20;:32::i;:::-;8617:47:18::1;8640:4;8646:2;8650:7;8659:4;8617:22;:47::i;:::-;8459:210:::0;;;;;:::o;917:409:7:-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5169:1:18;1064:25:7;;;:53;;;1104:13;;1093:7;:24;;1064:53;1060:102;;;1141:9;917:409;-1:-1:-1;;917:409:7:o;1060:102::-;-1:-1:-1;1184:20:7;;;;:11;:20;;;;;;;;;1172:32;;;;;;;;;-1:-1:-1;;;;;1172:32:7;;;;-1:-1:-1;;;1172:32:7;;-1:-1:-1;;;;;1172:32:7;;;;;;;;-1:-1:-1;;;1172:32:7;;;;;;;;;;;;;;;;1215:65;;1259:9;917:409;-1:-1:-1;;917:409:7:o;1215:65::-;1297:21;1310:7;1297:12;:21::i;6979:383:18:-;7052:13;7083:16;7091:7;7083;:16::i;:::-;7078:59;;7108:29;;-1:-1:-1;;;7108:29:18;;;;;;;;;;;7078:59;7154:9;;;;;;;:18;;7167:5;7154:18;7150:76;;7196:18;7189:25;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6979:383;;;:::o;7150:76::-;7238:21;7262:12;7238:36;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7316:7;7325:18;:7;:16;:18::i;:::-;7299:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;7285:69;;;6979:383;;;:::o;5576:115::-;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;5653:14:18::1;:30:::0;5576:115::o;1398:31::-;;;;;;;:::i;5318:115::-;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;5395:14:18::1;:30:::0;5318:115::o;6257:92::-;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;6321:9:18::1;:20:::0;;;::::1;;::::0;::::1;-1:-1:-1::0;;6321:20:18;;::::1;::::0;;;::::1;::::0;;6257:92::o;9695:164:6:-;-1:-1:-1;;;;;9816:25:6;;;9792:4;9816:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;9695:164::o;5922:107:18:-;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;5995:12:18::1;:26:::0;5922:107::o;1972:201:16:-;1136:6;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;-1:-1:-1;;;;;2061:22:16;::::1;2053:73;;;::::0;-1:-1:-1;;;2053:73:16;;16112:2:20;2053:73:16::1;::::0;::::1;16094:21:20::0;16151:2;16131:18;;;16124:30;16190:34;16170:18;;;16163:62;-1:-1:-1;;;16241:18:20;;;16234:36;16287:19;;2053:73:16::1;15910:402:20::0;2053:73:16::1;2137:28;2156:8;2137:18;:28::i;6038:99:18:-:0;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;6107:10:18::1;:22:::0;6038:99::o;5187:123::-;1136:6:16;;-1:-1:-1;;;;;1136:6:16;736:10:1;1283:23:16;1275:68;;;;-1:-1:-1;;;1275:68:16;;;;;;;:::i;:::-;5268:16:18::1;:34:::0;5187:123::o;4437:305:6:-;4539:4;-1:-1:-1;;;;;;4576:40:6;;-1:-1:-1;;;4576:40:6;;:105;;-1:-1:-1;;;;;;;4633:48:6;;-1:-1:-1;;;4633:48:6;4576:105;:158;;;;4698:36;4722:11;4698:23;:36::i;11229:104::-;11298:27;11308:2;11312:8;11298:27;;;;;;;;;;;;:9;:27::i;11047:174::-;11104:4;11147:7;5169:1:18;11128:26:6;;:53;;;;;11168:13;;11158:7;:23;11128:53;:85;;;;-1:-1:-1;;11186:20:6;;;;:11;:20;;;;;:27;-1:-1:-1;;;11186:27:6;;;;11185:28;;11047:174::o;2301:419:15:-;822:42;2492:45;:49;2488:225;;2563:67;;-1:-1:-1;;;2563:67:15;;2614:4;2563:67;;;16529:34:20;-1:-1:-1;;;;;16599:15:20;;16579:18;;;16572:43;822:42:15;;2563;;16464:18:20;;2563:67:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2558:144;;2658:28;;-1:-1:-1;;;2658:28:15;;-1:-1:-1;;;;;1970:32:20;;2658:28:15;;;1952:51:20;1925:18;;2658:28:15;1806:203:20;8616:379:6;8697:13;8713:24;8729:7;8713:15;:24::i;:::-;8697:40;;8758:5;-1:-1:-1;;;;;8752:11:6;:2;-1:-1:-1;;;;;8752:11:6;;8748:48;;8772:24;;-1:-1:-1;;;8772:24:6;;;;;;;;;;;8748:48;736:10:1;-1:-1:-1;;;;;8813:21:6;;;;;;:63;;-1:-1:-1;8839:37:6;8856:5;736:10:1;9695:164:6;:::i;8839:37::-;8838:38;8813:63;8809:138;;;8900:35;;-1:-1:-1;;;8900:35:6;;;;;;;;;;;8809:138;8959:28;8968:2;8972:7;8981:5;8959:8;:28::i;9926:170::-;10060:28;10070:4;10076:2;10080:7;10060:9;:28::i;2471:317:0:-;2586:6;2561:21;:31;;2553:73;;;;-1:-1:-1;;;2553:73:0;;17078:2:20;2553:73:0;;;17060:21:20;17117:2;17097:18;;;17090:30;17156:31;17136:18;;;17129:59;17205:18;;2553:73:0;16876:353:20;2553:73:0;2640:12;2658:9;-1:-1:-1;;;;;2658:14:0;2680:6;2658:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2639:52;;;2710:7;2702:78;;;;-1:-1:-1;;;2702:78:0;;17646:2:20;2702:78:0;;;17628:21:20;17685:2;17665:18;;;17658:30;17724:34;17704:18;;;17697:62;17795:28;17775:18;;;17768:56;17841:19;;2702:78:0;17444:422:20;10167:185:6;10305:39;10322:4;10328:2;10332:7;10305:39;;;;;;;;;;;;:16;:39::i;1182:190:14:-;1307:4;1360;1331:25;1344:5;1351:4;1331:12;:25::i;:::-;:33;;1182:190;-1:-1:-1;;;;1182:190:14:o;6187:1109:6:-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;6298:7:6;;5169:1:18;6347:23:6;;:47;;;;;6381:13;;6374:4;:20;6347:47;6343:886;;;6415:31;6449:17;;;:11;:17;;;;;;;;;6415:51;;;;;;;;;-1:-1:-1;;;;;6415:51:6;;;;-1:-1:-1;;;6415:51:6;;-1:-1:-1;;;;;6415:51:6;;;;;;;;-1:-1:-1;;;6415:51:6;;;;;;;;;;;;;;6485:729;;6535:14;;-1:-1:-1;;;;;6535:28:6;;6531:101;;6599:9;6187:1109;-1:-1:-1;;;6187:1109:6:o;6531:101::-;-1:-1:-1;;;6974:6:6;7019:17;;;;:11;:17;;;;;;;;;7007:29;;;;;;;;;-1:-1:-1;;;;;7007:29:6;;;;;-1:-1:-1;;;7007:29:6;;-1:-1:-1;;;;;7007:29:6;;;;;;;;-1:-1:-1;;;7007:29:6;;;;;;;;;;;;;7067:28;7063:109;;7135:9;6187:1109;-1:-1:-1;;;6187:1109:6:o;7063:109::-;6934:261;;;6396:833;6343:886;7257:31;;-1:-1:-1;;;7257:31:6;;;;;;;;;;;2766:332:5;2482:5;-1:-1:-1;;;;;2869:33:5;;;;2861:88;;;;-1:-1:-1;;;2861:88:5;;18073:2:20;2861:88:5;;;18055:21:20;18112:2;18092:18;;;18085:30;18151:34;18131:18;;;18124:62;-1:-1:-1;;;18202:18:20;;;18195:40;18252:19;;2861:88:5;17871:406:20;2861:88:5;-1:-1:-1;;;;;2968:22:5;;2960:60;;;;-1:-1:-1;;;2960:60:5;;18484:2:20;2960:60:5;;;18466:21:20;18523:2;18503:18;;;18496:30;18562:27;18542:18;;;18535:55;18607:18;;2960:60:5;18282:349:20;2960:60:5;3055:35;;;;;;;;;-1:-1:-1;;;;;3055:35:5;;;;;;-1:-1:-1;;;;;3055:35:5;;;;;;;;;;-1:-1:-1;;;3033:57:5;;;;-1:-1:-1;3033:57:5;2766:332::o;2333:191:16:-;2426:6;;;-1:-1:-1;;;;;2443:17:16;;;-1:-1:-1;;;;;;2443:17:16;;;;;;;2476:40;;2426:6;;;2443:17;2426:6;;2476:40;;2407:16;;2476:40;2396:128;2333:191;:::o;9337:287:6:-;736:10:1;-1:-1:-1;;;;;9436:24:6;;;9432:54;;9469:17;;-1:-1:-1;;;9469:17:6;;;;;;;;;;;9432:54;736:10:1;9499:32:6;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;9499:42:6;;;;;;;;;;;;:53;;-1:-1:-1;;9499:53:6;;;;;;;;;;9568:48;;636:41:20;;;9499:42:6;;736:10:1;9568:48:6;;609:18:20;9568:48:6;;;;;;;9337:287;;:::o;10423:369::-;10590:28;10600:4;10606:2;10610:7;10590:9;:28::i;:::-;-1:-1:-1;;;;;10633:13:6;;1505:19:0;:23;;10633:76:6;;;;;10653:56;10684:4;10690:2;10694:7;10703:5;10653:30;:56::i;:::-;10652:57;10633:76;10629:156;;;10733:40;;-1:-1:-1;;;10733:40:6;;;;;;;;;;;342:723:19;398:13;619:5;628:1;619:10;615:53;;-1:-1:-1;;646:10:19;;;;;;;;;;;;-1:-1:-1;;;646:10:19;;;;;342:723::o;615:53::-;693:5;678:12;734:78;741:9;;734:78;;767:8;;;;:::i;:::-;;-1:-1:-1;790:10:19;;-1:-1:-1;798:2:19;790:10;;:::i;:::-;;;734:78;;;822:19;854:6;-1:-1:-1;;;;;844:17:19;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;844:17:19;;822:39;;872:154;879:10;;872:154;;906:11;916:1;906:11;;:::i;:::-;;-1:-1:-1;975:10:19;983:2;975:5;:10;:::i;:::-;962:24;;:2;:24;:::i;:::-;949:39;;932:6;939;932:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;932:56:19;;;;;;;;-1:-1:-1;1003:11:19;1012:2;1003:11;;:::i;:::-;;;872:154;;;1050:6;342:723;-1:-1:-1;;;;342:723:19:o;1404:215:5:-;1506:4;-1:-1:-1;;;;;;1530:41:5;;-1:-1:-1;;;1530:41:5;;:81;;-1:-1:-1;;;;;;;;;;963:40:4;;;1575:36:5;854:157:4;11696:163:6;11819:32;11825:2;11829:8;11839:5;11846:4;11819:5;:32::i;19204:196::-;19319:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;19319:29:6;-1:-1:-1;;;;;19319:29:6;;;;;;;;;19364:28;;19319:24;;19364:28;;;;;;;19204:196;;;:::o;14147:2130::-;14262:35;14300:21;14313:7;14300:12;:21::i;:::-;14262:59;;14360:4;-1:-1:-1;;;;;14338:26:6;:13;:18;;;-1:-1:-1;;;;;14338:26:6;;14334:67;;14373:28;;-1:-1:-1;;;14373:28:6;;;;;;;;;;;14334:67;14414:22;736:10:1;-1:-1:-1;;;;;14440:20:6;;;;:73;;-1:-1:-1;14477:36:6;14494:4;736:10:1;9695:164:6;:::i;14477:36::-;14440:126;;;-1:-1:-1;736:10:1;14530:20:6;14542:7;14530:11;:20::i;:::-;-1:-1:-1;;;;;14530:36:6;;14440:126;14414:153;;14585:17;14580:66;;14611:35;;-1:-1:-1;;;14611:35:6;;;;;;;;;;;14580:66;-1:-1:-1;;;;;14661:16:6;;14657:52;;14686:23;;-1:-1:-1;;;14686:23:6;;;;;;;;;;;14657:52;14830:35;14847:1;14851:7;14860:4;14830:8;:35::i;:::-;-1:-1:-1;;;;;15161:18:6;;;;;;;:12;:18;;;;;;;;:31;;-1:-1:-1;;15161:31:6;;;-1:-1:-1;;;;;15161:31:6;;;-1:-1:-1;;15161:31:6;;;;;;;15207:16;;;;;;;;;:29;;;;;;;;-1:-1:-1;15207:29:6;;;;;;;;;;;15287:20;;;:11;:20;;;;;;15322:18;;-1:-1:-1;;;;;;15355:49:6;;;;-1:-1:-1;;;15388:15:6;15355:49;;;;;;;;;;15678:11;;15738:24;;;;;15781:13;;15287:20;;15738:24;;15781:13;15777:384;;15991:13;;15976:11;:28;15972:174;;16029:20;;16098:28;;;;-1:-1:-1;;;;;16072:54:6;-1:-1:-1;;;16072:54:6;-1:-1:-1;;;;;;16072:54:6;;;-1:-1:-1;;;;;16029:20:6;;16072:54;;;;15972:174;15136:1036;;;16208:7;16204:2;-1:-1:-1;;;;;16189:27:6;16198:4;-1:-1:-1;;;;;16189:27:6;;;;;;;;;;;16227:42;8133:154:18;2049:296:14;2132:7;2175:4;2132:7;2190:118;2214:5;:12;2210:1;:16;2190:118;;;2263:33;2273:12;2287:5;2293:1;2287:8;;;;;;;;:::i;:::-;;;;;;;2263:9;:33::i;:::-;2248:48;-1:-1:-1;2228:3:14;;;;:::i;:::-;;;;2190:118;;19892:667:6;20076:72;;-1:-1:-1;;;20076:72:6;;20055:4;;-1:-1:-1;;;;;20076:36:6;;;;;:72;;736:10:1;;20127:4:6;;20133:7;;20142:5;;20076:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20076:72:6;;;;;;;;-1:-1:-1;;20076:72:6;;;;;;;;;;;;:::i;:::-;;;20072:480;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20310:6;:13;20327:1;20310:18;20306:235;;20356:40;;-1:-1:-1;;;20356:40:6;;;;;;;;;;;20306:235;20499:6;20493:13;20484:6;20480:2;20476:15;20469:38;20072:480;-1:-1:-1;;;;;;20195:55:6;-1:-1:-1;;;20195:55:6;;-1:-1:-1;19892:667:6;;;;;;:::o;12118:1775::-;12280:13;;-1:-1:-1;;;;;12308:16:6;;12304:48;;12333:19;;-1:-1:-1;;;12333:19:6;;;;;;;;;;;12304:48;12367:8;12379:1;12367:13;12363:44;;12389:18;;-1:-1:-1;;;12389:18:6;;;;;;;;;;;12363:44;-1:-1:-1;;;;;12758:16:6;;;;;;:12;:16;;;;;;;;:44;;-1:-1:-1;;12817:49:6;;-1:-1:-1;;;;;12758:44:6;;;;;;;12817:49;;;;-1:-1:-1;;12758:44:6;;;;;;12817:49;;;;;;;;;;;;;;;;12883:25;;;:11;:25;;;;;;:35;;-1:-1:-1;;;;;;12933:66:6;;;;-1:-1:-1;;;12983:15:6;12933:66;;;;;;;;;;12883:25;13080:23;;;13124:4;:23;;;;-1:-1:-1;;;;;;13132:13:6;;1505:19:0;:23;;13132:15:6;13120:641;;;13168:314;13199:38;;13224:12;;-1:-1:-1;;;;;13199:38:6;;;13216:1;;13199:38;;13216:1;;13199:38;13265:69;13304:1;13308:2;13312:14;;;;;;13328:5;13265:30;:69::i;:::-;13260:174;;13370:40;;-1:-1:-1;;;13370:40:6;;;;;;;;;;;13260:174;13477:3;13461:12;:19;13168:314;;13563:12;13546:13;;:29;13542:43;;13577:8;;;13542:43;13120:641;;;13626:120;13657:40;;13682:14;;;;;-1:-1:-1;;;;;13657:40:6;;;13674:1;;13657:40;;13674:1;;13657:40;13741:3;13725:12;:19;13626:120;;13120:641;-1:-1:-1;13775:13:6;:28;13825:60;8133:154:18;9163:149:14;9226:7;9257:1;9253;:5;:51;;9388:13;9482:15;;;9518:4;9511:15;;;9565:4;9549:21;;9253:51;;;-1:-1:-1;9388:13:14;9482:15;;;9518:4;9511:15;9565:4;9549:21;;;9163:149::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:20;-1:-1:-1;;;;;;88:32:20;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;688:180::-;747:6;800:2;788:9;779:7;775:23;771:32;768:52;;;816:1;813;806:12;768:52;-1:-1:-1;839:23:20;;688:180;-1:-1:-1;688:180:20:o;1055:258::-;1127:1;1137:113;1151:6;1148:1;1145:13;1137:113;;;1227:11;;;1221:18;1208:11;;;1201:39;1173:2;1166:10;1137:113;;;1268:6;1265:1;1262:13;1259:48;;;-1:-1:-1;;1303:1:20;1285:16;;1278:27;1055:258::o;1318:::-;1360:3;1398:5;1392:12;1425:6;1420:3;1413:19;1441:63;1497:6;1490:4;1485:3;1481:14;1474:4;1467:5;1463:16;1441:63;:::i;:::-;1558:2;1537:15;-1:-1:-1;;1533:29:20;1524:39;;;;1565:4;1520:50;;1318:258;-1:-1:-1;;1318:258:20:o;1581:220::-;1730:2;1719:9;1712:21;1693:4;1750:45;1791:2;1780:9;1776:18;1768:6;1750:45;:::i;2014:173::-;2082:20;;-1:-1:-1;;;;;2131:31:20;;2121:42;;2111:70;;2177:1;2174;2167:12;2111:70;2014:173;;;:::o;2192:254::-;2260:6;2268;2321:2;2309:9;2300:7;2296:23;2292:32;2289:52;;;2337:1;2334;2327:12;2289:52;2360:29;2379:9;2360:29;:::i;:::-;2350:39;2436:2;2421:18;;;;2408:32;;-1:-1:-1;;;2192:254:20:o;2451:328::-;2528:6;2536;2544;2597:2;2585:9;2576:7;2572:23;2568:32;2565:52;;;2613:1;2610;2603:12;2565:52;2636:29;2655:9;2636:29;:::i;:::-;2626:39;;2684:38;2718:2;2707:9;2703:18;2684:38;:::i;:::-;2674:48;;2769:2;2758:9;2754:18;2741:32;2731:42;;2451:328;;;;;:::o;2784:248::-;2852:6;2860;2913:2;2901:9;2892:7;2888:23;2884:32;2881:52;;;2929:1;2926;2919:12;2881:52;-1:-1:-1;;2952:23:20;;;3022:2;3007:18;;;2994:32;;-1:-1:-1;2784:248:20:o;3738:118::-;3824:5;3817:13;3810:21;3803:5;3800:32;3790:60;;3846:1;3843;3836:12;3861:241;3917:6;3970:2;3958:9;3949:7;3945:23;3941:32;3938:52;;;3986:1;3983;3976:12;3938:52;4025:9;4012:23;4044:28;4066:5;4044:28;:::i;4107:127::-;4168:10;4163:3;4159:20;4156:1;4149:31;4199:4;4196:1;4189:15;4223:4;4220:1;4213:15;4239:275;4310:2;4304:9;4375:2;4356:13;;-1:-1:-1;;4352:27:20;4340:40;;-1:-1:-1;;;;;4395:34:20;;4431:22;;;4392:62;4389:88;;;4457:18;;:::i;:::-;4493:2;4486:22;4239:275;;-1:-1:-1;4239:275:20:o;4519:407::-;4584:5;-1:-1:-1;;;;;4610:6:20;4607:30;4604:56;;;4640:18;;:::i;:::-;4678:57;4723:2;4702:15;;-1:-1:-1;;4698:29:20;4729:4;4694:40;4678:57;:::i;:::-;4669:66;;4758:6;4751:5;4744:21;4798:3;4789:6;4784:3;4780:16;4777:25;4774:45;;;4815:1;4812;4805:12;4774:45;4864:6;4859:3;4852:4;4845:5;4841:16;4828:43;4918:1;4911:4;4902:6;4895:5;4891:18;4887:29;4880:40;4519:407;;;;;:::o;4931:451::-;5000:6;5053:2;5041:9;5032:7;5028:23;5024:32;5021:52;;;5069:1;5066;5059:12;5021:52;5109:9;5096:23;-1:-1:-1;;;;;5134:6:20;5131:30;5128:50;;;5174:1;5171;5164:12;5128:50;5197:22;;5250:4;5242:13;;5238:27;-1:-1:-1;5228:55:20;;5279:1;5276;5269:12;5228:55;5302:74;5368:7;5363:2;5350:16;5345:2;5341;5337:11;5302:74;:::i;5387:367::-;5450:8;5460:6;5514:3;5507:4;5499:6;5495:17;5491:27;5481:55;;5532:1;5529;5522:12;5481:55;-1:-1:-1;5555:20:20;;-1:-1:-1;;;;;5587:30:20;;5584:50;;;5630:1;5627;5620:12;5584:50;5667:4;5659:6;5655:17;5643:29;;5727:3;5720:4;5710:6;5707:1;5703:14;5695:6;5691:27;5687:38;5684:47;5681:67;;;5744:1;5741;5734:12;5759:511;5854:6;5862;5870;5923:2;5911:9;5902:7;5898:23;5894:32;5891:52;;;5939:1;5936;5929:12;5891:52;5962:29;5981:9;5962:29;:::i;:::-;5952:39;;6042:2;6031:9;6027:18;6014:32;-1:-1:-1;;;;;6061:6:20;6058:30;6055:50;;;6101:1;6098;6091:12;6055:50;6140:70;6202:7;6193:6;6182:9;6178:22;6140:70;:::i;:::-;5759:511;;6229:8;;-1:-1:-1;6114:96:20;;-1:-1:-1;;;;5759:511:20:o;6275:946::-;6359:6;6390:2;6433;6421:9;6412:7;6408:23;6404:32;6401:52;;;6449:1;6446;6439:12;6401:52;6489:9;6476:23;-1:-1:-1;;;;;6559:2:20;6551:6;6548:14;6545:34;;;6575:1;6572;6565:12;6545:34;6613:6;6602:9;6598:22;6588:32;;6658:7;6651:4;6647:2;6643:13;6639:27;6629:55;;6680:1;6677;6670:12;6629:55;6716:2;6703:16;6738:2;6734;6731:10;6728:36;;;6744:18;;:::i;:::-;6790:2;6787:1;6783:10;6773:20;;6813:28;6837:2;6833;6829:11;6813:28;:::i;:::-;6875:15;;;6945:11;;;6941:20;;;6906:12;;;;6973:19;;;6970:39;;;7005:1;7002;6995:12;6970:39;7029:11;;;;7049:142;7065:6;7060:3;7057:15;7049:142;;;7131:17;;7119:30;;7082:12;;;;7169;;;;7049:142;;;7210:5;6275:946;-1:-1:-1;;;;;;;;6275:946:20:o;7509:724::-;7744:2;7796:21;;;7866:13;;7769:18;;;7888:22;;;7715:4;;7744:2;7967:15;;;;7941:2;7926:18;;;7715:4;8010:197;8024:6;8021:1;8018:13;8010:197;;;8073:52;8121:3;8112:6;8106:13;7310:12;;-1:-1:-1;;;;;7306:38:20;7294:51;;7398:4;7387:16;;;7381:23;-1:-1:-1;;;;;7377:48:20;7361:14;;;7354:72;7489:4;7478:16;;;7472:23;7465:31;7458:39;7442:14;;7435:63;7226:278;8073:52;8182:15;;;;8154:4;8145:14;;;;;8046:1;8039:9;8010:197;;8238:292;8296:6;8349:2;8337:9;8328:7;8324:23;8320:32;8317:52;;;8365:1;8362;8355:12;8317:52;8404:9;8391:23;-1:-1:-1;;;;;8447:5:20;8443:38;8436:5;8433:49;8423:77;;8496:1;8493;8486:12;8535:186;8594:6;8647:2;8635:9;8626:7;8622:23;8618:32;8615:52;;;8663:1;8660;8653:12;8615:52;8686:29;8705:9;8686:29;:::i;8911:632::-;9082:2;9134:21;;;9204:13;;9107:18;;;9226:22;;;9053:4;;9082:2;9305:15;;;;9279:2;9264:18;;;9053:4;9348:169;9362:6;9359:1;9356:13;9348:169;;;9423:13;;9411:26;;9492:15;;;;9457:12;;;;9384:1;9377:9;9348:169;;9548:322;9625:6;9633;9641;9694:2;9682:9;9673:7;9669:23;9665:32;9662:52;;;9710:1;9707;9700:12;9662:52;9733:29;9752:9;9733:29;:::i;:::-;9723:39;9809:2;9794:18;;9781:32;;-1:-1:-1;9860:2:20;9845:18;;;9832:32;;9548:322;-1:-1:-1;;;9548:322:20:o;9875:1250::-;10013:4;10055:3;10044:9;10040:19;10032:27;;10092:6;10086:13;10075:9;10068:32;10156:4;10148:6;10144:17;10138:24;10131:4;10120:9;10116:20;10109:54;10219:4;10211:6;10207:17;10201:24;10194:4;10183:9;10179:20;10172:54;10282:4;10274:6;10270:17;10264:24;10257:4;10246:9;10242:20;10235:54;10345:4;10337:6;10333:17;10327:24;10320:4;10309:9;10305:20;10298:54;10408:4;10400:6;10396:17;10390:24;10383:4;10372:9;10368:20;10361:54;10471:4;10463:6;10459:17;10453:24;10446:4;10435:9;10431:20;10424:54;10525:4;10517:6;10513:17;10507:24;10540:51;10585:4;10574:9;10570:20;10556:12;470:13;463:21;451:34;;400:91;10540:51;-1:-1:-1;10610:6:20;10653:15;;;10647:22;470:13;463:21;10710:18;;;451:34;10748:6;10791:15;;;10785:22;470:13;463:21;10848:18;;;451:34;10886:6;10934:15;;;10928:22;10908:18;;;10901:50;10970:6;11018:15;;;11012:22;10992:18;;;10985:50;11054:6;11102:15;;;11096:22;11076:18;;;;11069:50;;;;11076:18;9875:1250::o;11130:315::-;11195:6;11203;11256:2;11244:9;11235:7;11231:23;11227:32;11224:52;;;11272:1;11269;11262:12;11224:52;11295:29;11314:9;11295:29;:::i;:::-;11285:39;;11374:2;11363:9;11359:18;11346:32;11387:28;11409:5;11387:28;:::i;:::-;11434:5;11424:15;;;11130:315;;;;;:::o;11450:437::-;11536:6;11544;11597:2;11585:9;11576:7;11572:23;11568:32;11565:52;;;11613:1;11610;11603:12;11565:52;11653:9;11640:23;-1:-1:-1;;;;;11678:6:20;11675:30;11672:50;;;11718:1;11715;11708:12;11672:50;11757:70;11819:7;11810:6;11799:9;11795:22;11757:70;:::i;:::-;11846:8;;11731:96;;-1:-1:-1;11450:437:20;-1:-1:-1;;;;11450:437:20:o;11892:667::-;11987:6;11995;12003;12011;12064:3;12052:9;12043:7;12039:23;12035:33;12032:53;;;12081:1;12078;12071:12;12032:53;12104:29;12123:9;12104:29;:::i;:::-;12094:39;;12152:38;12186:2;12175:9;12171:18;12152:38;:::i;:::-;12142:48;;12237:2;12226:9;12222:18;12209:32;12199:42;;12292:2;12281:9;12277:18;12264:32;-1:-1:-1;;;;;12311:6:20;12308:30;12305:50;;;12351:1;12348;12341:12;12305:50;12374:22;;12427:4;12419:13;;12415:27;-1:-1:-1;12405:55:20;;12456:1;12453;12446:12;12405:55;12479:74;12545:7;12540:2;12527:16;12522:2;12518;12514:11;12479:74;:::i;:::-;12469:84;;;11892:667;;;;;;;:::o;12564:267::-;7310:12;;-1:-1:-1;;;;;7306:38:20;7294:51;;7398:4;7387:16;;;7381:23;-1:-1:-1;;;;;7377:48:20;7361:14;;;7354:72;7489:4;7478:16;;;7472:23;7465:31;7458:39;7442:14;;;7435:63;12762:2;12747:18;;12774:51;7226:278;12836:260;12904:6;12912;12965:2;12953:9;12944:7;12940:23;12936:32;12933:52;;;12981:1;12978;12971:12;12933:52;13004:29;13023:9;13004:29;:::i;:::-;12994:39;;13052:38;13086:2;13075:9;13071:18;13052:38;:::i;:::-;13042:48;;12836:260;;;;;:::o;13101:127::-;13162:10;13157:3;13153:20;13150:1;13143:31;13193:4;13190:1;13183:15;13217:4;13214:1;13207:15;13233:128;13273:3;13304:1;13300:6;13297:1;13294:13;13291:39;;;13310:18;;:::i;:::-;-1:-1:-1;13346:9:20;;13233:128::o;13366:168::-;13406:7;13472:1;13468;13464:6;13460:14;13457:1;13454:21;13449:1;13442:9;13435:17;13431:45;13428:71;;;13479:18;;:::i;:::-;-1:-1:-1;13519:9:20;;13366:168::o;13539:380::-;13618:1;13614:12;;;;13661;;;13682:61;;13736:4;13728:6;13724:17;13714:27;;13682:61;13789:2;13781:6;13778:14;13758:18;13755:38;13752:161;;13835:10;13830:3;13826:20;13823:1;13816:31;13870:4;13867:1;13860:15;13898:4;13895:1;13888:15;13752:161;;13539:380;;;:::o;13924:127::-;13985:10;13980:3;13976:20;13973:1;13966:31;14016:4;14013:1;14006:15;14040:4;14037:1;14030:15;14056:120;14096:1;14122;14112:35;;14127:18;;:::i;:::-;-1:-1:-1;14161:9:20;;14056:120::o;14181:356::-;14383:2;14365:21;;;14402:18;;;14395:30;14461:34;14456:2;14441:18;;14434:62;14528:2;14513:18;;14181:356::o;15136:127::-;15197:10;15192:3;15188:20;15185:1;15178:31;15228:4;15225:1;15218:15;15252:4;15249:1;15242:15;15268:637;15548:3;15586:6;15580:13;15602:53;15648:6;15643:3;15636:4;15628:6;15624:17;15602:53;:::i;:::-;15718:13;;15677:16;;;;15740:57;15718:13;15677:16;15774:4;15762:17;;15740:57;:::i;:::-;-1:-1:-1;;;15819:20:20;;15848:22;;;15897:1;15886:13;;15268:637;-1:-1:-1;;;;15268:637:20:o;16626:245::-;16693:6;16746:2;16734:9;16725:7;16721:23;16717:32;16714:52;;;16762:1;16759;16752:12;16714:52;16794:9;16788:16;16813:28;16835:5;16813:28;:::i;18636:135::-;18675:3;18696:17;;;18693:43;;18716:18;;:::i;:::-;-1:-1:-1;18763:1:20;18752:13;;18636:135::o;18776:125::-;18816:4;18844:1;18841;18838:8;18835:34;;;18849:18;;:::i;:::-;-1:-1:-1;18886:9:20;;18776:125::o;18906:112::-;18938:1;18964;18954:35;;18969:18;;:::i;:::-;-1:-1:-1;19003:9:20;;18906:112::o;19023:489::-;-1:-1:-1;;;;;19292:15:20;;;19274:34;;19344:15;;19339:2;19324:18;;19317:43;19391:2;19376:18;;19369:34;;;19439:3;19434:2;19419:18;;19412:31;;;19217:4;;19460:46;;19486:19;;19478:6;19460:46;:::i;:::-;19452:54;19023:489;-1:-1:-1;;;;;;19023:489:20:o;19517:249::-;19586:6;19639:2;19627:9;19618:7;19614:23;19610:32;19607:52;;;19655:1;19652;19645:12;19607:52;19687:9;19681:16;19706:30;19730:5;19706:30;:::i

Swarm Source

ipfs://cb22fbdbfca1b59d20997d3125261da6743fc511828b830f8a001cc9f874a4db
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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