ETH Price: $3,335.79 (-3.73%)
Gas: 4 Gwei

Token

Passkeys (Passkeys)
 

Overview

Max Total Supply

4,450 Passkeys

Holders

118

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
0x68e09Ad98B46A306F0C6D5a92438eab2E6Bc10fa
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

PassKeys reflect the power of community-driven NFT curation. We're not just a marketplace; we're a dynamic ecosystem where creators shape NFT culture collaboratively. Our commitment to decentralisation empowers every voice

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
PassKeys

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-09-04
*/

// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

// Openzeppelin helpers

// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)

// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC1155/ERC1155.sol)

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

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

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

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 id,
        uint256 value
    );

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(
        address indexed account,
        address indexed operator,
        bool approved
    );

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(
        address account,
        uint256 id
    ) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(
        address[] calldata accounts,
        uint256[] calldata ids
    ) external view returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(
        address account,
        address operator
    ) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)

/**
 * @dev _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {
    /**
     * @dev Handles the receipt of a single ERC1155 token type. This function is
     * called at the end of a `safeTransferFrom` after the balance has been updated.
     *
     * NOTE: To accept the transfer, this must return
     * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
     * (i.e. 0xf23a6e61, or its own function selector).
     *
     * @param operator The address which initiated the transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param id The ID of the token being transferred
     * @param value The amount of tokens being transferred
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
     * @dev Handles the receipt of a multiple ERC1155 token types. This function
     * is called at the end of a `safeBatchTransferFrom` after the balances have
     * been updated.
     *
     * NOTE: To accept the transfer(s), this must return
     * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
     * (i.e. 0xbc197c81, or its own function selector).
     *
     * @param operator The address which initiated the batch transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param ids An array containing ids of each token being transferred (order and length must match values array)
     * @param values An array containing amounts of each token being transferred (order and length must match ids array)
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
     */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)

/**
 * @dev Interface of the optional ERC1155MetadataExtension interface, as defined
 * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155MetadataURI is IERC1155 {
    /**
     * @dev Returns the URI for token type `id`.
     *
     * If the `\{id\}` substring is present in the URI, it must be replaced by
     * clients with the actual token type ID.
     */
    function uri(uint256 id) external view returns (string memory);
}

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

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.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;
    }
}

/**
 * @dev Implementation of the basic standard multi-token.
 * See https://eips.ethereum.org/EIPS/eip-1155
 * Originally based on code by Enjin: https://github.com/enjin/erc-1155
 *
 * _Available since v3.1._
 */
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
    using Address for address;

    // Mapping from token ID to account balances
    mapping(uint256 => mapping(address => uint256)) private _balances;

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

    // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
    string internal _uri;

    /**
     * @dev See {_setURI}.
     */
    constructor(string memory uri_) {
        _setURI(uri_);
    }

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

    /**
     * @dev See {IERC1155MetadataURI-uri}.
     *
     * This implementation returns the same URI for *all* token types. It relies
     * on the token type ID substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * Clients calling this function must replace the `\{id\}` substring with the
     * actual token type ID.
     */
    function uri(uint256) public view virtual override returns (string memory) {
        return _uri;
    }

    /**
     * @dev See {IERC1155-balanceOf}.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(
        address account,
        uint256 id
    ) public view virtual override returns (uint256) {
        require(
            account != address(0),
            "ERC1155: address zero is not a valid owner"
        );
        return _balances[id][account];
    }

    /**
     * @dev See {IERC1155-balanceOfBatch}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(
        address[] memory accounts,
        uint256[] memory ids
    ) public view virtual override returns (uint256[] memory) {
        require(
            accounts.length == ids.length,
            "ERC1155: accounts and ids length mismatch"
        );

        uint256[] memory batchBalances = new uint256[](accounts.length);

        for (uint256 i = 0; i < accounts.length; ++i) {
            batchBalances[i] = balanceOf(accounts[i], ids[i]);
        }

        return batchBalances;
    }

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

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

    /**
     * @dev See {IERC1155-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: caller is not token owner or approved"
        );
        _safeTransferFrom(from, to, id, amount, data);
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: caller is not token owner or approved"
        );
        _safeBatchTransferFrom(from, to, ids, amounts, data);
    }

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        uint256 fromBalance = _balances[id][from];
        require(
            fromBalance >= amount,
            "ERC1155: insufficient balance for transfer"
        );
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }
        _balances[id][to] += amount;

        emit TransferSingle(operator, from, to, id, amount);

        _afterTokenTransfer(operator, from, to, ids, amounts, data);

        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(
            ids.length == amounts.length,
            "ERC1155: ids and amounts length mismatch"
        );
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(
                fromBalance >= amount,
                "ERC1155: insufficient balance for transfer"
            );
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
            _balances[id][to] += amount;
        }

        emit TransferBatch(operator, from, to, ids, amounts);

        _afterTokenTransfer(operator, from, to, ids, amounts, data);

        _doSafeBatchTransferAcceptanceCheck(
            operator,
            from,
            to,
            ids,
            amounts,
            data
        );
    }

    /**
     * @dev Sets a new URI for all token types, by relying on the token type ID
     * substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * By this mechanism, any occurrence of the `\{id\}` substring in either the
     * URI or any of the amounts in the JSON file at said URI will be replaced by
     * clients with the token type ID.
     *
     * For example, the `https://token-cdn-domain/\{id\}.json` URI would be
     * interpreted by clients as
     * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
     * for token type ID 0x4cce0.
     *
     * See {uri}.
     *
     * Because these URIs cannot be meaningfully represented by the {URI} event,
     * this function emits no events.
     */
    function _setURI(string memory newuri) internal virtual {
        _uri = newuri;
    }

    /**
     * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _mint(
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        _balances[id][to] += amount;
        emit TransferSingle(operator, address(0), to, id, amount);

        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);

        _doSafeTransferAcceptanceCheck(
            operator,
            address(0),
            to,
            id,
            amount,
            data
        );
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _mintBatch(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");
        require(
            ids.length == amounts.length,
            "ERC1155: ids and amounts length mismatch"
        );

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; i++) {
            _balances[ids[i]][to] += amounts[i];
        }

        emit TransferBatch(operator, address(0), to, ids, amounts);

        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);

        _doSafeBatchTransferAcceptanceCheck(
            operator,
            address(0),
            to,
            ids,
            amounts,
            data
        );
    }

    /**
     * @dev Destroys `amount` tokens of token type `id` from `from`
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `from` must have at least `amount` tokens of token type `id`.
     */
    function _burn(address from, uint256 id, uint256 amount) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, from, address(0), ids, amounts, "");

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }

        emit TransferSingle(operator, from, address(0), id, amount);

        _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     */
    function _burnBatch(
        address from,
        uint256[] memory ids,
        uint256[] memory amounts
    ) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");
        require(
            ids.length == amounts.length,
            "ERC1155: ids and amounts length mismatch"
        );

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, address(0), ids, amounts, "");

        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(
                fromBalance >= amount,
                "ERC1155: burn amount exceeds balance"
            );
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
        }

        emit TransferBatch(operator, from, address(0), ids, amounts);

        _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
    }

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

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `ids` and `amounts` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}

    /**
     * @dev Hook that is called after any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `id` and `amount` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}

    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try
                IERC1155Receiver(to).onERC1155Received(
                    operator,
                    from,
                    id,
                    amount,
                    data
                )
            returns (bytes4 response) {
                if (response != IERC1155Receiver.onERC1155Received.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non-ERC1155Receiver implementer");
            }
        }
    }

    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try
                IERC1155Receiver(to).onERC1155BatchReceived(
                    operator,
                    from,
                    ids,
                    amounts,
                    data
                )
            returns (bytes4 response) {
                if (
                    response != IERC1155Receiver.onERC1155BatchReceived.selector
                ) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non-ERC1155Receiver implementer");
            }
        }
    }

    function _asSingletonArray(
        uint256 element
    ) private pure returns (uint256[] memory) {
        uint256[] memory array = new uint256[](1);
        array[0] = element;

        return array;
    }
}

/**
 * @dev Extension of ERC1155 that adds tracking of total supply per id.
 *
 * Useful for scenarios where Fungible and Non-fungible tokens have to be
 * clearly identified. Note: While a totalSupply of 1 might mean the
 * corresponding is an NFT, there is no guarantees that no other token with the
 * same id are not going to be minted.
 */
abstract contract ERC1155Supply is ERC1155 {
    mapping(uint256 => uint256) private _totalSupply;

    /**
     * @dev Total amount of tokens in with a given id.
     */
    function totalSupply(uint256 id) public view virtual returns (uint256) {
        return _totalSupply[id];
    }

    /**
     * @dev Indicates whether any token exist with a given id, or not.
     */
    function exists(uint256 id) public view virtual returns (bool) {
        return ERC1155Supply.totalSupply(id) > 0;
    }

    /**
     * @dev See {ERC1155-_beforeTokenTransfer}.
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual override {
        super._beforeTokenTransfer(operator, from, to, ids, amounts, data);

        if (from == address(0)) {
            for (uint256 i = 0; i < ids.length; ++i) {
                _totalSupply[ids[i]] += amounts[i];
            }
        }

        if (to == address(0)) {
            for (uint256 i = 0; i < ids.length; ++i) {
                uint256 id = ids[i];
                uint256 amount = amounts[i];
                uint256 supply = _totalSupply[id];
                require(
                    supply >= amount,
                    "ERC1155: burn amount exceeds totalSupply"
                );
                unchecked {
                    _totalSupply[id] = supply - amount;
                }
            }
        }
    }
}

// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.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 Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

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

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

// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(
        uint256 a,
        Rounding rounding
    ) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return
                result +
                (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(
        uint256 value,
        Rounding rounding
    ) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return
                result +
                (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(
        uint256 value,
        Rounding rounding
    ) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return
                result +
                (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(
        uint256 value,
        Rounding rounding
    ) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return
                result +
                (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

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

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

/// @title PassKeys ERC1155 Contract
/// @notice This contract allows users to claim their passkeys, which come in three types: bronze (2221 copies), silver (1388 copies), and gold (841 copies).
contract PassKeys is ERC1155Supply, Ownable {
    using MerkleProof for bytes32[];
    using Strings for uint256;

    /*//////////////////////////////////////////////////////////////
                           STATE VARIABLES
    //////////////////////////////////////////////////////////////*/

    // ID of the gold passkey
    uint256 public constant GOLD_KEY = 1;

    // ID of the silver passkey
    uint256 public constant SILVER_KEY = 2;

    // ID of the bronze passkey
    uint256 public constant BRONZE_KEY = 3;

    // Maximum supply (copies) of gold passkey
    uint256 public constant GOLD_SUPPLY = 841;

    // Maximum supply (copies) of silver passkey
    uint256 public constant SILVER_SUPPLY = 1388;

    // Maximum supply (copies) of bronze passkey
    uint256 public constant BRONZE_SUPPLY = 2221;

    // Stores merkle root used to verify the eligibility of an address for claiming passkeys
    bytes32 public merkleRoot;

    // Keeps track of how many copies of a specific passkey type an address has minted.
    mapping(uint256 => mapping(address => uint256)) public passkeyMintCount;

    /*//////////////////////////////////////////////////////////////
                                EVENTS
    //////////////////////////////////////////////////////////////*/

    event MerkleRootChanged(bytes32 newMerkleRoot);
    event PassKeyMinted(
        address indexed recipient,
        uint256 indexed keyType,
        uint256 indexed amount
    );
    event URIChanged(string newURI);

    /*//////////////////////////////////////////////////////////////
                                 ERRORS
    //////////////////////////////////////////////////////////////*/

    error ClaimNotAllowedYet();
    error ClaimVerificationFailed();
    error ExceedsBronzeKeySupply();
    error ExceedsSilverKeySupply();
    error ExceedsGoldKeySupply();
    error ExceedsAllowedPasskeyMintAmount();
    error SameValueAsOld();
    error ZeroAmount();

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

    /// @notice Constructor function to set the token URI.
    /// @param _tokenURI URL of PassKey tokens.
    constructor(string memory _tokenURI) ERC1155(_tokenURI) {}

    /*//////////////////////////////////////////////////////////////
                      OWNER RESTRICTED FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @notice Sets a new Merkle root.
    /// @dev This function can only be called by the contract owner.
    /// @param _newMerkleRoot The new Merkle root to set.
    function setMerkleRoot(bytes32 _newMerkleRoot) external onlyOwner {
        // Ensure the new Merkle root is different from the current one.
        if (merkleRoot == _newMerkleRoot) {
            revert SameValueAsOld();
        }

        // Update the Merkle root to the new value.
        merkleRoot = _newMerkleRoot;

        // Emit an event to signal the change in the Merkle root.
        emit MerkleRootChanged(_newMerkleRoot);
    }

    /// @notice Sets a new URI for all token types. Can only be called by the owner of this contract.
    /// @param _newuri URL of the new URI.
    function setURI(string calldata _newuri) external onlyOwner {
        // Overwrites old uri.
        _setURI(_newuri);

        emit URIChanged(_newuri);
    }

    /*//////////////////////////////////////////////////////////////
                           CLAIM FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @notice Allows the caller to claim a Bronze PassKey by providing a valid merkle proof.
    /// @param _amount The amount of Bronze PassKey to claim.
    /// @param _allowedLimit The maximum allowed limit that can be claimed by the caller.
    /// @param _merkleProof The merkle proof data for verifying the claim.
    function claimBronzePassKey(
        uint256 _amount,
        uint256 _allowedLimit,
        bytes32[] calldata _merkleProof
    ) external {
        // Revert if the claim amount would exceed the total supply of Bronze PassKeys.
        if (totalSupply(BRONZE_KEY) + _amount > BRONZE_SUPPLY) {
            revert ExceedsBronzeKeySupply();
        }

        // Perform necessary sanity checks and then mint the Bronze PassKeys.
        _claimKey(BRONZE_KEY, _amount, _allowedLimit, _merkleProof);
    }

    /// @notice Allows the caller to claim a Silver PassKey by providing a valid merkle proof.
    /// @param _amount The amount of Silver PassKey to claim.
    /// @param _allowedLimit The maximum allowed limit that can be claimed by the caller.
    /// @param _merkleProof The merkle proof data for verifying the claim.
    function claimSilverPassKey(
        uint256 _amount,
        uint256 _allowedLimit,
        bytes32[] calldata _merkleProof
    ) external {
        // Revert if the claim amount would exceed the total supply of Silver PassKeys.
        if (totalSupply(SILVER_KEY) + _amount > SILVER_SUPPLY) {
            revert ExceedsSilverKeySupply();
        }

        // Perform necessary sanity checks and then mint the Silver PassKeys.
        _claimKey(SILVER_KEY, _amount, _allowedLimit, _merkleProof);
    }

    /// @notice Allows the caller to claim a Gold PassKey by providing a valid merkle proof.
    /// @param _amount The amount of Gold PassKey to claim.
    /// @param _allowedLimit The maximum allowed limit that can be claimed by the caller.
    /// @param _merkleProof The merkle proof data for verifying the claim.
    function claimGoldPassKey(
        uint256 _amount,
        uint256 _allowedLimit,
        bytes32[] calldata _merkleProof
    ) external {
        // Revert if the claim amount would exceed the total supply of Gold PassKeys.
        if (totalSupply(GOLD_KEY) + _amount > GOLD_SUPPLY) {
            revert ExceedsGoldKeySupply();
        }

        // Perform necessary sanity checks and then mint the Gold PassKeys.
        _claimKey(GOLD_KEY, _amount, _allowedLimit, _merkleProof);
    }

    /// @dev Performs some essential sanity checks and subsequently mints the specified type of passkey to the caller.
    /// @param _keyType The type of PassKey being claimed.
    /// @param _amount The amount of PassKeys to be claimed.
    /// @param _allowedLimit The maximum allowed limit that can be claimed by the caller.
    /// @param _merkleProof The merkle proof data for verifying the claim.
    function _claimKey(
        uint256 _keyType,
        uint256 _amount,
        uint256 _allowedLimit,
        bytes32[] calldata _merkleProof
    ) private {
        // Revert if the merkle root is not set.
        if (merkleRoot == bytes32(0)) {
            revert ClaimNotAllowedYet();
        }

        // Revert if the amount to claim is zero.
        if (_amount == 0) {
            revert ZeroAmount();
        }

        // Verify if a caller address is eligible to claim a certain amount of a certain passkey.
        if (
            !MerkleProof.verify(
                _merkleProof,
                merkleRoot,
                keccak256(abi.encodePacked(_keyType, msg.sender, _allowedLimit))
            )
        ) {
            revert ClaimVerificationFailed();
        }

        // Revert if the requested claim amount would cause the caller to exceed their allocated claim limit for a specific passkey.
        if (passkeyMintCount[_keyType][msg.sender] + _amount > _allowedLimit) {
            revert ExceedsAllowedPasskeyMintAmount();
        }

        // Add the requested claim amount to the caller's passkey mint count.
        passkeyMintCount[_keyType][msg.sender] += _amount;

        emit PassKeyMinted(msg.sender, _keyType, _amount);

        // Mint PassKey for caller.
        _mint(msg.sender, _keyType, _amount, "");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC1155 FUNCTION
    //////////////////////////////////////////////////////////////*/

    // Function to get the URI for a specific token
    function uri(uint256 tokenId) public view override returns (string memory) {
        return
            bytes(_uri).length > 0
                ? string(abi.encodePacked(_uri, tokenId.toString()))
                : "";
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_tokenURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ClaimNotAllowedYet","type":"error"},{"inputs":[],"name":"ClaimVerificationFailed","type":"error"},{"inputs":[],"name":"ExceedsAllowedPasskeyMintAmount","type":"error"},{"inputs":[],"name":"ExceedsBronzeKeySupply","type":"error"},{"inputs":[],"name":"ExceedsGoldKeySupply","type":"error"},{"inputs":[],"name":"ExceedsSilverKeySupply","type":"error"},{"inputs":[],"name":"SameValueAsOld","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","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":false,"internalType":"bytes32","name":"newMerkleRoot","type":"bytes32"}],"name":"MerkleRootChanged","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":"recipient","type":"address"},{"indexed":true,"internalType":"uint256","name":"keyType","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PassKeyMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"newURI","type":"string"}],"name":"URIChanged","type":"event"},{"inputs":[],"name":"BRONZE_KEY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BRONZE_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GOLD_KEY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GOLD_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SILVER_KEY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SILVER_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_allowedLimit","type":"uint256"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"claimBronzePassKey","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_allowedLimit","type":"uint256"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"claimGoldPassKey","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_allowedLimit","type":"uint256"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"claimSilverPassKey","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"passkeyMintCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","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":"bytes32","name":"_newMerkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newuri","type":"string"}],"name":"setURI","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":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b5060405162002541380380620025418339810160408190526200003491620000cd565b80620000408162000053565b506200004c3362000065565b50620002fd565b600262000061828262000231565b5050565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b60006020808385031215620000e157600080fd5b82516001600160401b0380821115620000f957600080fd5b818501915085601f8301126200010e57600080fd5b815181811115620001235762000123620000b7565b604051601f8201601f19908116603f011681019083821181831017156200014e576200014e620000b7565b8160405282815288868487010111156200016757600080fd5b600093505b828410156200018b57848401860151818501870152928501926200016c565b600086848301015280965050505050505092915050565b600181811c90821680620001b757607f821691505b602082108103620001d857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200022c57600081815260208120601f850160051c81016020861015620002075750805b601f850160051c820191505b81811015620002285782815560010162000213565b5050505b505050565b81516001600160401b038111156200024d576200024d620000b7565b62000265816200025e8454620001a2565b84620001de565b602080601f8311600181146200029d5760008415620002845750858301515b600019600386901b1c1916600185901b17855562000228565b600085815260208120601f198616915b82811015620002ce57888601518255948401946001909101908401620002ad565b5085821015620002ed5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b612234806200030d6000396000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c80637e12cee4116100de578063bd85b03911610097578063e985e9c511610071578063e985e9c514610365578063f242432a146103a1578063f2fde38b146103b4578063ff861541146103c757600080fd5b8063bd85b03914610312578063c133bf1e14610332578063c8b86b0a1461035d57600080fd5b80637e12cee4146102ae578063807864dd146102c157806383cadc11146102c9578063871fbf3e146102dc5780638da5cb5b146102e4578063a22cb465146102ff57600080fd5b80632eb4a7ab1161014b57806352289514116101255780635228951414610281578063641c99511461028a578063715018a6146102935780637cb647591461029b57600080fd5b80632eb4a7ab146102365780634e1273f41461023f5780634f558e791461025f57600080fd5b8062fdd58e1461019257806301ffc9a7146101b857806302fe5305146101db5780630e89341c146101f05780631652f52b146102105780632eb2c2d614610223575b600080fd5b6101a56101a0366004611703565b6103d0565b6040519081526020015b60405180910390f35b6101cb6101c6366004611743565b610469565b60405190151581526020016101af565b6101ee6101e9366004611760565b6104b9565b005b6102036101fe3660046117d2565b61053d565b6040516101af919061183b565b6101ee61021e36600461184e565b61059b565b6101ee610231366004611a1d565b610609565b6101a560055481565b61025261024d366004611ac7565b610655565b6040516101af9190611bcd565b6101cb61026d3660046117d2565b600090815260036020526040902054151590565b6101a561056c81565b6101a561034981565b6101ee61077f565b6101ee6102a93660046117d2565b610793565b6101ee6102bc36600461184e565b6107f8565b6101a5600381565b6101ee6102d736600461184e565b610860565b6101a5600281565b6004546040516001600160a01b0390911681526020016101af565b6101ee61030d366004611be0565b6108c8565b6101a56103203660046117d2565b60009081526003602052604090205490565b6101a5610340366004611c1c565b600660209081526000928352604080842090915290825290205481565b6101a5600181565b6101cb610373366004611c48565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205460ff1690565b6101ee6103af366004611c72565b6108d7565b6101ee6103c2366004611cd7565b61091c565b6101a56108ad81565b60006001600160a01b0383166104405760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b60648201526084015b60405180910390fd5b506000818152602081815260408083206001600160a01b03861684529091529020545b92915050565b60006001600160e01b03198216636cdb3d1360e11b148061049a57506001600160e01b031982166303a24d0760e21b145b8061046357506301ffc9a760e01b6001600160e01b0319831614610463565b6104c1610995565b61050082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506109ef92505050565b7fbd06d92759c326896ec0f7c3a981e801ae4644e020f89b2a198909b692df0ddd8282604051610531929190611cf2565b60405180910390a15050565b606060006002805461054e90611d21565b90501161056a5760405180602001604052806000815250610463565b6002610575836109fb565b604051602001610586929190611d5b565b60405160208183030381529060405292915050565b600160005260036020527fa15bc60c955c405d20d9149c709e2460f1c2d9a497496a7f46004d1772c3054c54610349906105d6908690611df8565b11156105f557604051637232218560e11b815260040160405180910390fd5b610603600185858585610a8e565b50505050565b6001600160a01b03851633148061062557506106258533610373565b6106415760405162461bcd60e51b815260040161043790611e0b565b61064e8585858585610c30565b5050505050565b606081518351146106ba5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b6064820152608401610437565b6000835167ffffffffffffffff8111156106d6576106d66118d1565b6040519080825280602002602001820160405280156106ff578160200160208202803683370190505b50905060005b84518110156107775761074a85828151811061072357610723611e59565b602002602001015185838151811061073d5761073d611e59565b60200260200101516103d0565b82828151811061075c5761075c611e59565b602090810291909101015261077081611e6f565b9050610705565b509392505050565b610787610995565b6107916000610e1b565b565b61079b610995565b80600554036107bd57604051631c71591d60e11b815260040160405180910390fd5b60058190556040518181527f1b930366dfeaa7eb3b325021e4ae81e36527063452ee55b86c95f85b36f4c31c9060200160405180910390a150565b600360008190526020527fcbc4e5fb02c3d1de23a9f1e014b4d2ee5aeaea9505df5e855c9210bf472495af546108ad90610833908690611df8565b111561085257604051632c3e828160e21b815260040160405180910390fd5b610603600385858585610a8e565b600260005260036020527fc3a24b0501bd2c13a7e57f2db4369ec4c223447539fc0724a9d55ac4a06ebd4d5461056c9061089b908690611df8565b11156108ba5760405163d7355b0360e01b815260040160405180910390fd5b610603600285858585610a8e565b6108d3338383610e6d565b5050565b6001600160a01b0385163314806108f357506108f38533610373565b61090f5760405162461bcd60e51b815260040161043790611e0b565b61064e8585858585610f4d565b610924610995565b6001600160a01b0381166109895760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610437565b61099281610e1b565b50565b6004546001600160a01b031633146107915760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b60026108d38282611ed3565b60606000610a0883611085565b600101905060008167ffffffffffffffff811115610a2857610a286118d1565b6040519080825280601f01601f191660200182016040528015610a52576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610a5c57509392505050565b600554610aae576040516316f83da760e31b815260040160405180910390fd5b83600003610acf57604051631f2a200560e01b815260040160405180910390fd5b610b558282808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060055460408051602081018c90526bffffffffffffffffffffffff193360601b16918101919091526054810189905290925060740190506040516020818303038152906040528051906020012061115d565b610b7257604051636f2fb49960e11b815260040160405180910390fd5b60008581526006602090815260408083203384529091529020548390610b99908690611df8565b1115610bb857604051636838f3bf60e11b815260040160405180910390fd5b600085815260066020908152604080832033845290915281208054869290610be1908490611df8565b90915550506040518490869033907f58aa53c0a75d38fd4e6c80f2468af22a157a1e30afffdf22e6626a1cf4f597db90600090a461064e33868660405180602001604052806000815250611173565b8151835114610c925760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608401610437565b6001600160a01b038416610cb85760405162461bcd60e51b815260040161043790611f93565b33610cc7818787878787611296565b60005b8451811015610dad576000858281518110610ce757610ce7611e59565b602002602001015190506000858381518110610d0557610d05611e59565b602090810291909101810151600084815280835260408082206001600160a01b038e168352909352919091205490915081811015610d555760405162461bcd60e51b815260040161043790611fd8565b6000838152602081815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290610d92908490611df8565b9250508190555050505080610da690611e6f565b9050610cca565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610dfd929190612022565b60405180910390a4610e1381878787878761140f565b505050505050565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b031603610ee05760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b6064820152608401610437565b6001600160a01b03838116600081815260016020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b038416610f735760405162461bcd60e51b815260040161043790611f93565b336000610f7f8561156a565b90506000610f8c8561156a565b9050610f9c838989858589611296565b6000868152602081815260408083206001600160a01b038c16845290915290205485811015610fdd5760405162461bcd60e51b815260040161043790611fd8565b6000878152602081815260408083206001600160a01b038d8116855292528083208985039055908a1682528120805488929061101a908490611df8565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461107a848a8a8a8a8a6115b5565b505050505050505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106110c45772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106110f0576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061110e57662386f26fc10000830492506010015b6305f5e1008310611126576305f5e100830492506008015b612710831061113a57612710830492506004015b6064831061114c576064830492506002015b600a83106104635760010192915050565b60008261116a8584611670565b14949350505050565b6001600160a01b0384166111d35760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608401610437565b3360006111df8561156a565b905060006111ec8561156a565b90506111fd83600089858589611296565b6000868152602081815260408083206001600160a01b038b1684529091528120805487929061122d908490611df8565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461128d836000898989896115b5565b50505050505050565b6001600160a01b03851661131d5760005b835181101561131b578281815181106112c2576112c2611e59565b6020026020010151600360008684815181106112e0576112e0611e59565b6020026020010151815260200190815260200160002060008282546113059190611df8565b90915550611314905081611e6f565b90506112a7565b505b6001600160a01b038416610e135760005b835181101561128d57600084828151811061134b5761134b611e59565b60200260200101519050600084838151811061136957611369611e59565b60200260200101519050600060036000848152602001908152602001600020549050818110156113ec5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f74604482015267616c537570706c7960c01b6064820152608401610437565b6000928352600360205260409092209103905561140881611e6f565b905061132e565b6001600160a01b0384163b15610e135760405163bc197c8160e01b81526001600160a01b0385169063bc197c81906114539089908990889088908890600401612050565b6020604051808303816000875af192505050801561148e575060408051601f3d908101601f1916820190925261148b918101906120ae565b60015b61153a5761149a6120cb565b806308c379a0036114d357506114ae6120e7565b806114b957506114d5565b8060405162461bcd60e51b8152600401610437919061183b565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b6064820152608401610437565b6001600160e01b0319811663bc197c8160e01b1461128d5760405162461bcd60e51b815260040161043790612171565b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106115a4576115a4611e59565b602090810291909101015292915050565b6001600160a01b0384163b15610e135760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906115f990899089908890889088906004016121b9565b6020604051808303816000875af1925050508015611634575060408051601f3d908101601f19168201909252611631918101906120ae565b60015b6116405761149a6120cb565b6001600160e01b0319811663f23a6e6160e01b1461128d5760405162461bcd60e51b815260040161043790612171565b600081815b8451811015610777576116a18286838151811061169457611694611e59565b60200260200101516116b5565b9150806116ad81611e6f565b915050611675565b60008183106116d15760008281526020849052604090206116e0565b60008381526020839052604090205b9392505050565b80356001600160a01b03811681146116fe57600080fd5b919050565b6000806040838503121561171657600080fd5b61171f836116e7565b946020939093013593505050565b6001600160e01b03198116811461099257600080fd5b60006020828403121561175557600080fd5b81356116e08161172d565b6000806020838503121561177357600080fd5b823567ffffffffffffffff8082111561178b57600080fd5b818501915085601f83011261179f57600080fd5b8135818111156117ae57600080fd5b8660208285010111156117c057600080fd5b60209290920196919550909350505050565b6000602082840312156117e457600080fd5b5035919050565b60005b838110156118065781810151838201526020016117ee565b50506000910152565b600081518084526118278160208601602086016117eb565b601f01601f19169290920160200192915050565b6020815260006116e0602083018461180f565b6000806000806060858703121561186457600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561188a57600080fd5b818701915087601f83011261189e57600080fd5b8135818111156118ad57600080fd5b8860208260051b85010111156118c257600080fd5b95989497505060200194505050565b634e487b7160e01b600052604160045260246000fd5b601f8201601f1916810167ffffffffffffffff8111828210171561190d5761190d6118d1565b6040525050565b600067ffffffffffffffff82111561192e5761192e6118d1565b5060051b60200190565b600082601f83011261194957600080fd5b8135602061195682611914565b60405161196382826118e7565b83815260059390931b850182019282810191508684111561198357600080fd5b8286015b8481101561199e5780358352918301918301611987565b509695505050505050565b600082601f8301126119ba57600080fd5b813567ffffffffffffffff8111156119d4576119d46118d1565b6040516119eb601f8301601f1916602001826118e7565b818152846020838601011115611a0057600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a08688031215611a3557600080fd5b611a3e866116e7565b9450611a4c602087016116e7565b9350604086013567ffffffffffffffff80821115611a6957600080fd5b611a7589838a01611938565b94506060880135915080821115611a8b57600080fd5b611a9789838a01611938565b93506080880135915080821115611aad57600080fd5b50611aba888289016119a9565b9150509295509295909350565b60008060408385031215611ada57600080fd5b823567ffffffffffffffff80821115611af257600080fd5b818501915085601f830112611b0657600080fd5b81356020611b1382611914565b604051611b2082826118e7565b83815260059390931b8501820192828101915089841115611b4057600080fd5b948201945b83861015611b6557611b56866116e7565b82529482019490820190611b45565b96505086013592505080821115611b7b57600080fd5b50611b8885828601611938565b9150509250929050565b600081518084526020808501945080840160005b83811015611bc257815187529582019590820190600101611ba6565b509495945050505050565b6020815260006116e06020830184611b92565b60008060408385031215611bf357600080fd5b611bfc836116e7565b915060208301358015158114611c1157600080fd5b809150509250929050565b60008060408385031215611c2f57600080fd5b82359150611c3f602084016116e7565b90509250929050565b60008060408385031215611c5b57600080fd5b611c64836116e7565b9150611c3f602084016116e7565b600080600080600060a08688031215611c8a57600080fd5b611c93866116e7565b9450611ca1602087016116e7565b93506040860135925060608601359150608086013567ffffffffffffffff811115611ccb57600080fd5b611aba888289016119a9565b600060208284031215611ce957600080fd5b6116e0826116e7565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b600181811c90821680611d3557607f821691505b602082108103611d5557634e487b7160e01b600052602260045260246000fd5b50919050565b6000808454611d6981611d21565b60018281168015611d815760018114611d9657611dc5565b60ff1984168752821515830287019450611dc5565b8860005260208060002060005b85811015611dbc5781548a820152908401908201611da3565b50505082870194505b505050508351611dd98183602088016117eb565b01949350505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561046357610463611de2565b6020808252602e908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526d195c881bdc88185c1c1c9bdd995960921b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b600060018201611e8157611e81611de2565b5060010190565b601f821115611ece57600081815260208120601f850160051c81016020861015611eaf5750805b601f850160051c820191505b81811015610e1357828155600101611ebb565b505050565b815167ffffffffffffffff811115611eed57611eed6118d1565b611f0181611efb8454611d21565b84611e88565b602080601f831160018114611f365760008415611f1e5750858301515b600019600386901b1c1916600185901b178555610e13565b600085815260208120601f198616915b82811015611f6557888601518255948401946001909101908401611f46565b5085821015611f835787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b6040815260006120356040830185611b92565b82810360208401526120478185611b92565b95945050505050565b6001600160a01b0386811682528516602082015260a06040820181905260009061207c90830186611b92565b828103606084015261208e8186611b92565b905082810360808401526120a2818561180f565b98975050505050505050565b6000602082840312156120c057600080fd5b81516116e08161172d565b600060033d11156120e45760046000803e5060005160e01c5b90565b600060443d10156120f55790565b6040516003193d81016004833e81513d67ffffffffffffffff816024840111818411171561212557505050505090565b828501915081518181111561213d5750505050505090565b843d87010160208285010111156121575750505050505090565b612166602082860101876118e7565b509095945050505050565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190526000906121f39083018461180f565b97965050505050505056fea2646970667358221220282e08a9624beed61fe286b1d68198f3bc33bfa32d233ba95751a617fb8eae6464736f6c634300081100330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005868747470733a2f2f6e667473746f726167652e6c696e6b2f697066732f62616679626569677473336a64637572346a7676736d613371766b33696e713372336978676e7232676573346877726e797979346562736461652f0000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061018d5760003560e01c80637e12cee4116100de578063bd85b03911610097578063e985e9c511610071578063e985e9c514610365578063f242432a146103a1578063f2fde38b146103b4578063ff861541146103c757600080fd5b8063bd85b03914610312578063c133bf1e14610332578063c8b86b0a1461035d57600080fd5b80637e12cee4146102ae578063807864dd146102c157806383cadc11146102c9578063871fbf3e146102dc5780638da5cb5b146102e4578063a22cb465146102ff57600080fd5b80632eb4a7ab1161014b57806352289514116101255780635228951414610281578063641c99511461028a578063715018a6146102935780637cb647591461029b57600080fd5b80632eb4a7ab146102365780634e1273f41461023f5780634f558e791461025f57600080fd5b8062fdd58e1461019257806301ffc9a7146101b857806302fe5305146101db5780630e89341c146101f05780631652f52b146102105780632eb2c2d614610223575b600080fd5b6101a56101a0366004611703565b6103d0565b6040519081526020015b60405180910390f35b6101cb6101c6366004611743565b610469565b60405190151581526020016101af565b6101ee6101e9366004611760565b6104b9565b005b6102036101fe3660046117d2565b61053d565b6040516101af919061183b565b6101ee61021e36600461184e565b61059b565b6101ee610231366004611a1d565b610609565b6101a560055481565b61025261024d366004611ac7565b610655565b6040516101af9190611bcd565b6101cb61026d3660046117d2565b600090815260036020526040902054151590565b6101a561056c81565b6101a561034981565b6101ee61077f565b6101ee6102a93660046117d2565b610793565b6101ee6102bc36600461184e565b6107f8565b6101a5600381565b6101ee6102d736600461184e565b610860565b6101a5600281565b6004546040516001600160a01b0390911681526020016101af565b6101ee61030d366004611be0565b6108c8565b6101a56103203660046117d2565b60009081526003602052604090205490565b6101a5610340366004611c1c565b600660209081526000928352604080842090915290825290205481565b6101a5600181565b6101cb610373366004611c48565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205460ff1690565b6101ee6103af366004611c72565b6108d7565b6101ee6103c2366004611cd7565b61091c565b6101a56108ad81565b60006001600160a01b0383166104405760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b60648201526084015b60405180910390fd5b506000818152602081815260408083206001600160a01b03861684529091529020545b92915050565b60006001600160e01b03198216636cdb3d1360e11b148061049a57506001600160e01b031982166303a24d0760e21b145b8061046357506301ffc9a760e01b6001600160e01b0319831614610463565b6104c1610995565b61050082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506109ef92505050565b7fbd06d92759c326896ec0f7c3a981e801ae4644e020f89b2a198909b692df0ddd8282604051610531929190611cf2565b60405180910390a15050565b606060006002805461054e90611d21565b90501161056a5760405180602001604052806000815250610463565b6002610575836109fb565b604051602001610586929190611d5b565b60405160208183030381529060405292915050565b600160005260036020527fa15bc60c955c405d20d9149c709e2460f1c2d9a497496a7f46004d1772c3054c54610349906105d6908690611df8565b11156105f557604051637232218560e11b815260040160405180910390fd5b610603600185858585610a8e565b50505050565b6001600160a01b03851633148061062557506106258533610373565b6106415760405162461bcd60e51b815260040161043790611e0b565b61064e8585858585610c30565b5050505050565b606081518351146106ba5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b6064820152608401610437565b6000835167ffffffffffffffff8111156106d6576106d66118d1565b6040519080825280602002602001820160405280156106ff578160200160208202803683370190505b50905060005b84518110156107775761074a85828151811061072357610723611e59565b602002602001015185838151811061073d5761073d611e59565b60200260200101516103d0565b82828151811061075c5761075c611e59565b602090810291909101015261077081611e6f565b9050610705565b509392505050565b610787610995565b6107916000610e1b565b565b61079b610995565b80600554036107bd57604051631c71591d60e11b815260040160405180910390fd5b60058190556040518181527f1b930366dfeaa7eb3b325021e4ae81e36527063452ee55b86c95f85b36f4c31c9060200160405180910390a150565b600360008190526020527fcbc4e5fb02c3d1de23a9f1e014b4d2ee5aeaea9505df5e855c9210bf472495af546108ad90610833908690611df8565b111561085257604051632c3e828160e21b815260040160405180910390fd5b610603600385858585610a8e565b600260005260036020527fc3a24b0501bd2c13a7e57f2db4369ec4c223447539fc0724a9d55ac4a06ebd4d5461056c9061089b908690611df8565b11156108ba5760405163d7355b0360e01b815260040160405180910390fd5b610603600285858585610a8e565b6108d3338383610e6d565b5050565b6001600160a01b0385163314806108f357506108f38533610373565b61090f5760405162461bcd60e51b815260040161043790611e0b565b61064e8585858585610f4d565b610924610995565b6001600160a01b0381166109895760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610437565b61099281610e1b565b50565b6004546001600160a01b031633146107915760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b60026108d38282611ed3565b60606000610a0883611085565b600101905060008167ffffffffffffffff811115610a2857610a286118d1565b6040519080825280601f01601f191660200182016040528015610a52576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610a5c57509392505050565b600554610aae576040516316f83da760e31b815260040160405180910390fd5b83600003610acf57604051631f2a200560e01b815260040160405180910390fd5b610b558282808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060055460408051602081018c90526bffffffffffffffffffffffff193360601b16918101919091526054810189905290925060740190506040516020818303038152906040528051906020012061115d565b610b7257604051636f2fb49960e11b815260040160405180910390fd5b60008581526006602090815260408083203384529091529020548390610b99908690611df8565b1115610bb857604051636838f3bf60e11b815260040160405180910390fd5b600085815260066020908152604080832033845290915281208054869290610be1908490611df8565b90915550506040518490869033907f58aa53c0a75d38fd4e6c80f2468af22a157a1e30afffdf22e6626a1cf4f597db90600090a461064e33868660405180602001604052806000815250611173565b8151835114610c925760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608401610437565b6001600160a01b038416610cb85760405162461bcd60e51b815260040161043790611f93565b33610cc7818787878787611296565b60005b8451811015610dad576000858281518110610ce757610ce7611e59565b602002602001015190506000858381518110610d0557610d05611e59565b602090810291909101810151600084815280835260408082206001600160a01b038e168352909352919091205490915081811015610d555760405162461bcd60e51b815260040161043790611fd8565b6000838152602081815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290610d92908490611df8565b9250508190555050505080610da690611e6f565b9050610cca565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610dfd929190612022565b60405180910390a4610e1381878787878761140f565b505050505050565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b031603610ee05760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b6064820152608401610437565b6001600160a01b03838116600081815260016020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b038416610f735760405162461bcd60e51b815260040161043790611f93565b336000610f7f8561156a565b90506000610f8c8561156a565b9050610f9c838989858589611296565b6000868152602081815260408083206001600160a01b038c16845290915290205485811015610fdd5760405162461bcd60e51b815260040161043790611fd8565b6000878152602081815260408083206001600160a01b038d8116855292528083208985039055908a1682528120805488929061101a908490611df8565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461107a848a8a8a8a8a6115b5565b505050505050505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106110c45772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106110f0576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061110e57662386f26fc10000830492506010015b6305f5e1008310611126576305f5e100830492506008015b612710831061113a57612710830492506004015b6064831061114c576064830492506002015b600a83106104635760010192915050565b60008261116a8584611670565b14949350505050565b6001600160a01b0384166111d35760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608401610437565b3360006111df8561156a565b905060006111ec8561156a565b90506111fd83600089858589611296565b6000868152602081815260408083206001600160a01b038b1684529091528120805487929061122d908490611df8565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461128d836000898989896115b5565b50505050505050565b6001600160a01b03851661131d5760005b835181101561131b578281815181106112c2576112c2611e59565b6020026020010151600360008684815181106112e0576112e0611e59565b6020026020010151815260200190815260200160002060008282546113059190611df8565b90915550611314905081611e6f565b90506112a7565b505b6001600160a01b038416610e135760005b835181101561128d57600084828151811061134b5761134b611e59565b60200260200101519050600084838151811061136957611369611e59565b60200260200101519050600060036000848152602001908152602001600020549050818110156113ec5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f74604482015267616c537570706c7960c01b6064820152608401610437565b6000928352600360205260409092209103905561140881611e6f565b905061132e565b6001600160a01b0384163b15610e135760405163bc197c8160e01b81526001600160a01b0385169063bc197c81906114539089908990889088908890600401612050565b6020604051808303816000875af192505050801561148e575060408051601f3d908101601f1916820190925261148b918101906120ae565b60015b61153a5761149a6120cb565b806308c379a0036114d357506114ae6120e7565b806114b957506114d5565b8060405162461bcd60e51b8152600401610437919061183b565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b6064820152608401610437565b6001600160e01b0319811663bc197c8160e01b1461128d5760405162461bcd60e51b815260040161043790612171565b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106115a4576115a4611e59565b602090810291909101015292915050565b6001600160a01b0384163b15610e135760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906115f990899089908890889088906004016121b9565b6020604051808303816000875af1925050508015611634575060408051601f3d908101601f19168201909252611631918101906120ae565b60015b6116405761149a6120cb565b6001600160e01b0319811663f23a6e6160e01b1461128d5760405162461bcd60e51b815260040161043790612171565b600081815b8451811015610777576116a18286838151811061169457611694611e59565b60200260200101516116b5565b9150806116ad81611e6f565b915050611675565b60008183106116d15760008281526020849052604090206116e0565b60008381526020839052604090205b9392505050565b80356001600160a01b03811681146116fe57600080fd5b919050565b6000806040838503121561171657600080fd5b61171f836116e7565b946020939093013593505050565b6001600160e01b03198116811461099257600080fd5b60006020828403121561175557600080fd5b81356116e08161172d565b6000806020838503121561177357600080fd5b823567ffffffffffffffff8082111561178b57600080fd5b818501915085601f83011261179f57600080fd5b8135818111156117ae57600080fd5b8660208285010111156117c057600080fd5b60209290920196919550909350505050565b6000602082840312156117e457600080fd5b5035919050565b60005b838110156118065781810151838201526020016117ee565b50506000910152565b600081518084526118278160208601602086016117eb565b601f01601f19169290920160200192915050565b6020815260006116e0602083018461180f565b6000806000806060858703121561186457600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561188a57600080fd5b818701915087601f83011261189e57600080fd5b8135818111156118ad57600080fd5b8860208260051b85010111156118c257600080fd5b95989497505060200194505050565b634e487b7160e01b600052604160045260246000fd5b601f8201601f1916810167ffffffffffffffff8111828210171561190d5761190d6118d1565b6040525050565b600067ffffffffffffffff82111561192e5761192e6118d1565b5060051b60200190565b600082601f83011261194957600080fd5b8135602061195682611914565b60405161196382826118e7565b83815260059390931b850182019282810191508684111561198357600080fd5b8286015b8481101561199e5780358352918301918301611987565b509695505050505050565b600082601f8301126119ba57600080fd5b813567ffffffffffffffff8111156119d4576119d46118d1565b6040516119eb601f8301601f1916602001826118e7565b818152846020838601011115611a0057600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a08688031215611a3557600080fd5b611a3e866116e7565b9450611a4c602087016116e7565b9350604086013567ffffffffffffffff80821115611a6957600080fd5b611a7589838a01611938565b94506060880135915080821115611a8b57600080fd5b611a9789838a01611938565b93506080880135915080821115611aad57600080fd5b50611aba888289016119a9565b9150509295509295909350565b60008060408385031215611ada57600080fd5b823567ffffffffffffffff80821115611af257600080fd5b818501915085601f830112611b0657600080fd5b81356020611b1382611914565b604051611b2082826118e7565b83815260059390931b8501820192828101915089841115611b4057600080fd5b948201945b83861015611b6557611b56866116e7565b82529482019490820190611b45565b96505086013592505080821115611b7b57600080fd5b50611b8885828601611938565b9150509250929050565b600081518084526020808501945080840160005b83811015611bc257815187529582019590820190600101611ba6565b509495945050505050565b6020815260006116e06020830184611b92565b60008060408385031215611bf357600080fd5b611bfc836116e7565b915060208301358015158114611c1157600080fd5b809150509250929050565b60008060408385031215611c2f57600080fd5b82359150611c3f602084016116e7565b90509250929050565b60008060408385031215611c5b57600080fd5b611c64836116e7565b9150611c3f602084016116e7565b600080600080600060a08688031215611c8a57600080fd5b611c93866116e7565b9450611ca1602087016116e7565b93506040860135925060608601359150608086013567ffffffffffffffff811115611ccb57600080fd5b611aba888289016119a9565b600060208284031215611ce957600080fd5b6116e0826116e7565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b600181811c90821680611d3557607f821691505b602082108103611d5557634e487b7160e01b600052602260045260246000fd5b50919050565b6000808454611d6981611d21565b60018281168015611d815760018114611d9657611dc5565b60ff1984168752821515830287019450611dc5565b8860005260208060002060005b85811015611dbc5781548a820152908401908201611da3565b50505082870194505b505050508351611dd98183602088016117eb565b01949350505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561046357610463611de2565b6020808252602e908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526d195c881bdc88185c1c1c9bdd995960921b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b600060018201611e8157611e81611de2565b5060010190565b601f821115611ece57600081815260208120601f850160051c81016020861015611eaf5750805b601f850160051c820191505b81811015610e1357828155600101611ebb565b505050565b815167ffffffffffffffff811115611eed57611eed6118d1565b611f0181611efb8454611d21565b84611e88565b602080601f831160018114611f365760008415611f1e5750858301515b600019600386901b1c1916600185901b178555610e13565b600085815260208120601f198616915b82811015611f6557888601518255948401946001909101908401611f46565b5085821015611f835787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b6040815260006120356040830185611b92565b82810360208401526120478185611b92565b95945050505050565b6001600160a01b0386811682528516602082015260a06040820181905260009061207c90830186611b92565b828103606084015261208e8186611b92565b905082810360808401526120a2818561180f565b98975050505050505050565b6000602082840312156120c057600080fd5b81516116e08161172d565b600060033d11156120e45760046000803e5060005160e01c5b90565b600060443d10156120f55790565b6040516003193d81016004833e81513d67ffffffffffffffff816024840111818411171561212557505050505090565b828501915081518181111561213d5750505050505090565b843d87010160208285010111156121575750505050505090565b612166602082860101876118e7565b509095945050505050565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190526000906121f39083018461180f565b97965050505050505056fea2646970667358221220282e08a9624beed61fe286b1d68198f3bc33bfa32d233ba95751a617fb8eae6464736f6c63430008110033

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

0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005868747470733a2f2f6e667473746f726167652e6c696e6b2f697066732f62616679626569677473336a64637572346a7676736d613371766b33696e713372336978676e7232676573346877726e797979346562736461652f0000000000000000

-----Decoded View---------------
Arg [0] : _tokenURI (string): https://nftstorage.link/ipfs/bafybeigts3jdcur4jvvsma3qvk3inq3r3ixgnr2ges4hwrnyyy4ebsdae/

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000058
Arg [2] : 68747470733a2f2f6e667473746f726167652e6c696e6b2f697066732f626166
Arg [3] : 79626569677473336a64637572346a7676736d613371766b33696e7133723369
Arg [4] : 78676e7232676573346877726e797979346562736461652f0000000000000000


Deployed Bytecode Sourcemap

68584:8520:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22246:292;;;;;;:::i;:::-;;:::i;:::-;;;597:25:1;;;585:2;570:18;22246:292:0;;;;;;;;21253:326;;;;;;:::i;:::-;;:::i;:::-;;;1184:14:1;;1177:22;1159:41;;1147:2;1132:18;21253:326:0;1019:187:1;71935:164:0;;;;;;:::i;:::-;;:::i;:::-;;76873:228;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;74313:501::-;;;;;;:::i;:::-;;:::i;24313:438::-;;;;;;:::i;:::-;;:::i;69527:25::-;;;;;;22704:536;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;39451:122::-;;;;;;:::i;:::-;39508:4;39329:16;;;:12;:16;;;;;;-1:-1:-1;;;39451:122:0;69277:44;;69317:4;69277:44;;69177:41;;69215:3;69177:41;;42469:103;;;:::i;71327:453::-;;;;;;:::i;:::-;;:::i;72619:515::-;;;;;;:::i;:::-;;:::i;69082:38::-;;69119:1;69082:38;;73468:515;;;;;;:::i;:::-;;:::i;69002:38::-;;69039:1;69002:38;;41821:87;41894:6;;41821:87;;-1:-1:-1;;;;;41894:6:0;;;8748:51:1;;8736:2;8721:18;41821:87:0;8602:203:1;23313:180:0;;;;;;:::i;:::-;;:::i;39240:113::-;;;;;;:::i;:::-;39302:7;39329:16;;;:12;:16;;;;;;;39240:113;69650:71;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;68924:36;;68959:1;68924:36;;23565:193;;;;;;:::i;:::-;-1:-1:-1;;;;;23713:27:0;;;23689:4;23713:27;;;:18;:27;;;;;;;;:37;;;;;;;;;;;;;;;23565:193;23830:406;;;;;;:::i;:::-;;:::i;42727:238::-;;;;;;:::i;:::-;;:::i;69380:44::-;;69420:4;69380:44;;22246:292;22357:7;-1:-1:-1;;;;;22399:21:0;;22377:113;;;;-1:-1:-1;;;22377:113:0;;10690:2:1;22377:113:0;;;10672:21:1;10729:2;10709:18;;;10702:30;10768:34;10748:18;;;10741:62;-1:-1:-1;;;10819:18:1;;;10812:40;10869:19;;22377:113:0;;;;;;;;;-1:-1:-1;22508:9:0;:13;;;;;;;;;;;-1:-1:-1;;;;;22508:22:0;;;;;;;;;;22246:292;;;;;:::o;21253:326::-;21371:4;-1:-1:-1;;;;;;21408:41:0;;-1:-1:-1;;;21408:41:0;;:110;;-1:-1:-1;;;;;;;21466:52:0;;-1:-1:-1;;;21466:52:0;21408:110;:163;;;-1:-1:-1;;;;;;;;;;20287:40:0;;;21535:36;20162:173;71935:164;41707:13;:11;:13::i;:::-;72038:16:::1;72046:7;;72038:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;72038:7:0::1;::::0;-1:-1:-1;;;72038:16:0:i:1;:::-;72072:19;72083:7;;72072:19;;;;;;;:::i;:::-;;;;;;;;71935:164:::0;;:::o;76873:228::-;76933:13;77000:1;76985:4;76979:18;;;;;:::i;:::-;;;:22;:114;;;;;;;;;;;;;;;;;77045:4;77051:18;:7;:16;:18::i;:::-;77028:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;76959:134;76873:228;-1:-1:-1;;76873:228:0:o;74313:501::-;68959:1;39302:7;39329:16;:12;:16;;;;69215:3;;74557:31;;74581:7;;74557:31;:::i;:::-;:45;74553:107;;;74626:22;;-1:-1:-1;;;74626:22:0;;;;;;;;;;;74553:107;74749:57;68959:1;74769:7;74778:13;74793:12;;74749:9;:57::i;:::-;74313:501;;;;:::o;24313:438::-;-1:-1:-1;;;;;24546:20:0;;19261:10;24546:20;;:60;;-1:-1:-1;24570:36:0;24587:4;19261:10;23565:193;:::i;24570:36::-;24524:156;;;;-1:-1:-1;;;24524:156:0;;;;;;;:::i;:::-;24691:52;24714:4;24720:2;24724:3;24729:7;24738:4;24691:22;:52::i;:::-;24313:438;;;;;:::o;22704:536::-;22840:16;22910:3;:10;22891:8;:15;:29;22869:120;;;;-1:-1:-1;;;22869:120:0;;13709:2:1;22869:120:0;;;13691:21:1;13748:2;13728:18;;;13721:30;13787:34;13767:18;;;13760:62;-1:-1:-1;;;13838:18:1;;;13831:39;13887:19;;22869:120:0;13507:405:1;22869:120:0;23002:30;23049:8;:15;23035:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;23035:30:0;;23002:63;;23083:9;23078:122;23102:8;:15;23098:1;:19;23078:122;;;23158:30;23168:8;23177:1;23168:11;;;;;;;;:::i;:::-;;;;;;;23181:3;23185:1;23181:6;;;;;;;;:::i;:::-;;;;;;;23158:9;:30::i;:::-;23139:13;23153:1;23139:16;;;;;;;;:::i;:::-;;;;;;;;;;:49;23119:3;;;:::i;:::-;;;23078:122;;;-1:-1:-1;23219:13:0;22704:536;-1:-1:-1;;;22704:536:0:o;42469:103::-;41707:13;:11;:13::i;:::-;42534:30:::1;42561:1;42534:18;:30::i;:::-;42469:103::o:0;71327:453::-;41707:13;:11;:13::i;:::-;71496:14:::1;71482:10;;:28:::0;71478:84:::1;;71534:16;;-1:-1:-1::0;;;71534:16:0::1;;;;;;;;;;;71478:84;71627:10;:27:::0;;;71739:33:::1;::::0;597:25:1;;;71739:33:0::1;::::0;585:2:1;570:18;71739:33:0::1;;;;;;;71327:453:::0;:::o;72619:515::-;69119:1;39302:7;39329:16;;;;;;;69420:4;;72867:33;;72893:7;;72867:33;:::i;:::-;:49;72863:113;;;72940:24;;-1:-1:-1;;;72940:24:0;;;;;;;;;;;72863:113;73067:59;69119:1;73089:7;73098:13;73113:12;;73067:9;:59::i;73468:515::-;69039:1;39302:7;39329:16;:12;:16;;;;69317:4;;73716:33;;73742:7;;73716:33;:::i;:::-;:49;73712:113;;;73789:24;;-1:-1:-1;;;73789:24:0;;;;;;;;;;;73712:113;73916:59;69039:1;73938:7;73947:13;73962:12;;73916:9;:59::i;23313:180::-;23433:52;19261:10;23466:8;23476;23433:18;:52::i;:::-;23313:180;;:::o;23830:406::-;-1:-1:-1;;;;;24038:20:0;;19261:10;24038:20;;:60;;-1:-1:-1;24062:36:0;24079:4;19261:10;23565:193;:::i;24062:36::-;24016:156;;;;-1:-1:-1;;;24016:156:0;;;;;;;:::i;:::-;24183:45;24201:4;24207:2;24211;24215:6;24223:4;24183:17;:45::i;42727:238::-;41707:13;:11;:13::i;:::-;-1:-1:-1;;;;;42830:22:0;::::1;42808:110;;;::::0;-1:-1:-1;;;42808:110:0;;14391:2:1;42808:110:0::1;::::0;::::1;14373:21:1::0;14430:2;14410:18;;;14403:30;14469:34;14449:18;;;14442:62;-1:-1:-1;;;14520:18:1;;;14513:36;14566:19;;42808:110:0::1;14189:402:1::0;42808:110:0::1;42929:28;42948:8;42929:18;:28::i;:::-;42727:238:::0;:::o;41986:132::-;41894:6;;-1:-1:-1;;;;;41894:6:0;19261:10;42050:23;42042:68;;;;-1:-1:-1;;;42042:68:0;;14798:2:1;42042:68:0;;;14780:21:1;;;14817:18;;;14810:30;14876:34;14856:18;;;14849:62;14928:18;;42042:68:0;14596:356:1;28749:88:0;28816:4;:13;28823:6;28816:4;:13;:::i;66468:716::-;66524:13;66575:14;66592:17;66603:5;66592:10;:17::i;:::-;66612:1;66592:21;66575:38;;66628:20;66662:6;66651:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66651:18:0;-1:-1:-1;66628:41:0;-1:-1:-1;66793:28:0;;;66809:2;66793:28;66850:288;-1:-1:-1;;66882:5:0;-1:-1:-1;;;67019:2:0;67008:14;;67003:30;66882:5;66990:44;67080:2;67071:11;;;-1:-1:-1;67101:21:0;66850:288;67101:21;-1:-1:-1;67159:6:0;66468:716;-1:-1:-1;;;66468:716:0:o;75231:1393::-;75457:10;;75453:84;;75505:20;;-1:-1:-1;;;75505:20:0;;;;;;;;;;;75453:84;75604:7;75615:1;75604:12;75600:64;;75640:12;;-1:-1:-1;;;75640:12:0;;;;;;;;;;;75600:64;75794:176;75831:12;;75794:176;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;75862:10:0;;75901:53;;;;;;17352:19:1;;;-1:-1:-1;;75928:10:0;17409:2:1;17405:15;17401:53;17387:12;;;17380:75;;;;17471:12;;;17464:28;;;75862:10:0;;-1:-1:-1;17508:12:1;;;-1:-1:-1;75901:53:0;;;;;;;;;;;;75891:64;;;;;;75794:18;:176::i;:::-;75775:266;;76004:25;;-1:-1:-1;;;76004:25:0;;;;;;;;;;;75775:266;76191:26;;;;:16;:26;;;;;;;;76218:10;76191:38;;;;;;;;76242:13;;76191:48;;76232:7;;76191:48;:::i;:::-;:64;76187:137;;;76279:33;;-1:-1:-1;;;76279:33:0;;;;;;;;;;;76187:137;76415:26;;;;:16;:26;;;;;;;;76442:10;76415:38;;;;;;;:49;;76457:7;;76415:26;:49;;76457:7;;76415:49;:::i;:::-;;;;-1:-1:-1;;76482:44:0;;76518:7;;76508:8;;76496:10;;76482:44;;;;;76576:40;76582:10;76594:8;76604:7;76576:40;;;;;;;;;;;;:5;:40::i;26584:1321::-;26825:7;:14;26811:3;:10;:28;26789:118;;;;-1:-1:-1;;;26789:118:0;;17733:2:1;26789:118:0;;;17715:21:1;17772:2;17752:18;;;17745:30;17811:34;17791:18;;;17784:62;-1:-1:-1;;;17862:18:1;;;17855:38;17910:19;;26789:118:0;17531:404:1;26789:118:0;-1:-1:-1;;;;;26926:16:0;;26918:66;;;;-1:-1:-1;;;26918:66:0;;;;;;;:::i;:::-;19261:10;27041:60;19261:10;27072:4;27078:2;27082:3;27087:7;27096:4;27041:20;:60::i;:::-;27119:9;27114:470;27138:3;:10;27134:1;:14;27114:470;;;27170:10;27183:3;27187:1;27183:6;;;;;;;;:::i;:::-;;;;;;;27170:19;;27204:14;27221:7;27229:1;27221:10;;;;;;;;:::i;:::-;;;;;;;;;;;;27248:19;27270:13;;;;;;;;;;-1:-1:-1;;;;;27270:19:0;;;;;;;;;;;;27221:10;;-1:-1:-1;27330:21:0;;;;27304:125;;;;-1:-1:-1;;;27304:125:0;;;;;;;:::i;:::-;27473:9;:13;;;;;;;;;;;-1:-1:-1;;;;;27473:19:0;;;;;;;;;;27495:20;;;27473:42;;27545:17;;;;;;;:27;;27495:20;;27473:9;27545:27;;27495:20;;27545:27;:::i;:::-;;;;;;;;27155:429;;;27150:3;;;;:::i;:::-;;;27114:470;;;;27631:2;-1:-1:-1;;;;;27601:47:0;27625:4;-1:-1:-1;;;;;27601:47:0;27615:8;-1:-1:-1;;;;;27601:47:0;;27635:3;27640:7;27601:47;;;;;;;:::i;:::-;;;;;;;;27733:164;27783:8;27806:4;27825:2;27842:3;27860:7;27882:4;27733:35;:164::i;:::-;26778:1127;26584:1321;;;;;:::o;43125:191::-;43218:6;;;-1:-1:-1;;;;;43235:17:0;;;-1:-1:-1;;;;;;43235:17:0;;;;;;;43268:40;;43218:6;;;43235:17;43218:6;;43268:40;;43199:16;;43268:40;43188:128;43125:191;:::o;33903:331::-;34058:8;-1:-1:-1;;;;;34049:17:0;:5;-1:-1:-1;;;;;34049:17:0;;34041:71;;;;-1:-1:-1;;;34041:71:0;;19429:2:1;34041:71:0;;;19411:21:1;19468:2;19448:18;;;19441:30;19507:34;19487:18;;;19480:62;-1:-1:-1;;;19558:18:1;;;19551:39;19607:19;;34041:71:0;19227:405:1;34041:71:0;-1:-1:-1;;;;;34123:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;34123:46:0;;;;;;;;;;34185:41;;1159::1;;;34185::0;;1132:18:1;34185:41:0;;;;;;;33903:331;;;:::o;25215:1011::-;-1:-1:-1;;;;;25403:16:0;;25395:66;;;;-1:-1:-1;;;25395:66:0;;;;;;;:::i;:::-;19261:10;25474:16;25539:21;25557:2;25539:17;:21::i;:::-;25516:44;;25571:24;25598:25;25616:6;25598:17;:25::i;:::-;25571:52;;25636:60;25657:8;25667:4;25673:2;25677:3;25682:7;25691:4;25636:20;:60::i;:::-;25709:19;25731:13;;;;;;;;;;;-1:-1:-1;;;;;25731:19:0;;;;;;;;;;25783:21;;;;25761:113;;;;-1:-1:-1;;;25761:113:0;;;;;;;:::i;:::-;25910:9;:13;;;;;;;;;;;-1:-1:-1;;;;;25910:19:0;;;;;;;;;;25932:20;;;25910:42;;25974:17;;;;;;;:27;;25932:20;;25910:9;25974:27;;25932:20;;25974:27;:::i;:::-;;;;-1:-1:-1;;26019:46:0;;;19811:25:1;;;19867:2;19852:18;;19845:34;;;-1:-1:-1;;;;;26019:46:0;;;;;;;;;;;;;;19784:18:1;26019:46:0;;;;;;;26150:68;26181:8;26191:4;26197:2;26201;26205:6;26213:4;26150:30;:68::i;:::-;25384:842;;;;25215:1011;;;;;:::o;63344:948::-;63397:7;;-1:-1:-1;;;63475:17:0;;63471:106;;-1:-1:-1;;;63513:17:0;;;-1:-1:-1;63559:2:0;63549:12;63471:106;63604:8;63595:5;:17;63591:106;;63642:8;63633:17;;;-1:-1:-1;63679:2:0;63669:12;63591:106;63724:8;63715:5;:17;63711:106;;63762:8;63753:17;;;-1:-1:-1;63799:2:0;63789:12;63711:106;63844:7;63835:5;:16;63831:103;;63881:7;63872:16;;;-1:-1:-1;63917:1:0;63907:11;63831:103;63961:7;63952:5;:16;63948:103;;63998:7;63989:16;;;-1:-1:-1;64034:1:0;64024:11;63948:103;64078:7;64069:5;:16;64065:103;;64115:7;64106:16;;;-1:-1:-1;64151:1:0;64141:11;64065:103;64195:7;64186:5;:16;64182:68;;64233:1;64223:11;64278:6;63344:948;-1:-1:-1;;63344:948:0:o;44445:190::-;44570:4;44623;44594:25;44607:5;44614:4;44594:12;:25::i;:::-;:33;;44445:190;-1:-1:-1;;;;44445:190:0:o;29223:818::-;-1:-1:-1;;;;;29376:16:0;;29368:62;;;;-1:-1:-1;;;29368:62:0;;20092:2:1;29368:62:0;;;20074:21:1;20131:2;20111:18;;;20104:30;20170:34;20150:18;;;20143:62;-1:-1:-1;;;20221:18:1;;;20214:31;20262:19;;29368:62:0;19890:397:1;29368:62:0;19261:10;29443:16;29508:21;29526:2;29508:17;:21::i;:::-;29485:44;;29540:24;29567:25;29585:6;29567:17;:25::i;:::-;29540:52;;29605:66;29626:8;29644:1;29648:2;29652:3;29657:7;29666:4;29605:20;:66::i;:::-;29684:9;:13;;;;;;;;;;;-1:-1:-1;;;;;29684:17:0;;;;;;;;;:27;;29705:6;;29684:9;:27;;29705:6;;29684:27;:::i;:::-;;;;-1:-1:-1;;29727:52:0;;;19811:25:1;;;19867:2;19852:18;;19845:34;;;-1:-1:-1;;;;;29727:52:0;;;;29760:1;;29727:52;;;;;;19784:18:1;29727:52:0;;;;;;;29870:163;29915:8;29946:1;29963:2;29980;29997:6;30018:4;29870:30;:163::i;:::-;29357:684;;;29223:818;;;;:::o;39648:992::-;-1:-1:-1;;;;;39970:18:0;;39966:160;;40010:9;40005:110;40029:3;:10;40025:1;:14;40005:110;;;40089:7;40097:1;40089:10;;;;;;;;:::i;:::-;;;;;;;40065:12;:20;40078:3;40082:1;40078:6;;;;;;;;:::i;:::-;;;;;;;40065:20;;;;;;;;;;;;:34;;;;;;;:::i;:::-;;;;-1:-1:-1;40041:3:0;;-1:-1:-1;40041:3:0;;:::i;:::-;;;40005:110;;;;39966:160;-1:-1:-1;;;;;40142:16:0;;40138:495;;40180:9;40175:447;40199:3;:10;40195:1;:14;40175:447;;;40235:10;40248:3;40252:1;40248:6;;;;;;;;:::i;:::-;;;;;;;40235:19;;40273:14;40290:7;40298:1;40290:10;;;;;;;;:::i;:::-;;;;;;;40273:27;;40319:14;40336:12;:16;40349:2;40336:16;;;;;;;;;;;;40319:33;;40411:6;40401;:16;;40371:130;;;;-1:-1:-1;;;40371:130:0;;20494:2:1;40371:130:0;;;20476:21:1;20533:2;20513:18;;;20506:30;20572:34;20552:18;;;20545:62;-1:-1:-1;;;20623:18:1;;;20616:38;20671:19;;40371:130:0;20292:404:1;40371:130:0;40553:16;;;;:12;:16;;;;;;40572:15;;40553:34;;40211:3;;;:::i;:::-;;;40175:447;;37502:975;-1:-1:-1;;;;;37742:13:0;;9812:19;:23;37738:732;;37795:203;;-1:-1:-1;;;37795:203:0;;-1:-1:-1;;;;;37795:43:0;;;;;:203;;37861:8;;37892:4;;37919:3;;37945:7;;37975:4;;37795:203;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37795:203:0;;;;;;;;-1:-1:-1;;37795:203:0;;;;;;;;;;;;:::i;:::-;;;37774:685;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;38332:6;38325:14;;-1:-1:-1;;;38325:14:0;;;;;;;;:::i;37774:685::-;;;38381:62;;-1:-1:-1;;;38381:62:0;;22849:2:1;38381:62:0;;;22831:21:1;22888:2;22868:18;;;22861:30;22927:34;22907:18;;;22900:62;-1:-1:-1;;;22978:18:1;;;22971:50;23038:19;;38381:62:0;22647:416:1;37774:685:0;-1:-1:-1;;;;;;38083:60:0;;-1:-1:-1;;;38083:60:0;38057:199;;38186:50;;-1:-1:-1;;;38186:50:0;;;;;;;:::i;38485:214::-;38621:16;;;38635:1;38621:16;;;;;;;;;38567;;38596:22;;38621:16;;;;;;;;;;;;-1:-1:-1;38621:16:0;38596:41;;38659:7;38648:5;38654:1;38648:8;;;;;;;;:::i;:::-;;;;;;;;;;:18;38686:5;38485:214;-1:-1:-1;;38485:214:0:o;36596:898::-;-1:-1:-1;;;;;36811:13:0;;9812:19;:23;36807:680;;36864:196;;-1:-1:-1;;;36864:196:0;;-1:-1:-1;;;;;36864:38:0;;;;;:196;;36925:8;;36956:4;;36983:2;;37008:6;;37037:4;;36864:196;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36864:196:0;;;;;;;;-1:-1:-1;;36864:196:0;;;;;;;;;;;;:::i;:::-;;;36843:633;;;;:::i;:::-;-1:-1:-1;;;;;;37123:55:0;;-1:-1:-1;;;37123:55:0;37119:154;;37203:50;;-1:-1:-1;;;37203:50:0;;;;;;;:::i;45312:321::-;45420:7;45463:4;45420:7;45478:118;45502:5;:12;45498:1;:16;45478:118;;;45551:33;45561:12;45575:5;45581:1;45575:8;;;;;;;;:::i;:::-;;;;;;;45551:9;:33::i;:::-;45536:48;-1:-1:-1;45516:3:0;;;;:::i;:::-;;;;45478:118;;52612:149;52675:7;52706:1;52702;:5;:51;;52862:13;52956:15;;;52992:4;52985:15;;;53039:4;53023:21;;52702:51;;;52862:13;52956:15;;;52992:4;52985:15;;;53039:4;53023:21;;52710:20;52695:58;52612:149;-1:-1:-1;;;52612:149:0:o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:254::-;260:6;268;321:2;309:9;300:7;296:23;292:32;289:52;;;337:1;334;327:12;289:52;360:29;379:9;360:29;:::i;:::-;350:39;436:2;421:18;;;;408:32;;-1:-1:-1;;;192:254:1:o;633:131::-;-1:-1:-1;;;;;;707:32:1;;697:43;;687:71;;754:1;751;744:12;769:245;827:6;880:2;868:9;859:7;855:23;851:32;848:52;;;896:1;893;886:12;848:52;935:9;922:23;954:30;978:5;954:30;:::i;1211:592::-;1282:6;1290;1343:2;1331:9;1322:7;1318:23;1314:32;1311:52;;;1359:1;1356;1349:12;1311:52;1399:9;1386:23;1428:18;1469:2;1461:6;1458:14;1455:34;;;1485:1;1482;1475:12;1455:34;1523:6;1512:9;1508:22;1498:32;;1568:7;1561:4;1557:2;1553:13;1549:27;1539:55;;1590:1;1587;1580:12;1539:55;1630:2;1617:16;1656:2;1648:6;1645:14;1642:34;;;1672:1;1669;1662:12;1642:34;1717:7;1712:2;1703:6;1699:2;1695:15;1691:24;1688:37;1685:57;;;1738:1;1735;1728:12;1685:57;1769:2;1761:11;;;;;1791:6;;-1:-1:-1;1211:592:1;;-1:-1:-1;;;;1211:592:1:o;1808:180::-;1867:6;1920:2;1908:9;1899:7;1895:23;1891:32;1888:52;;;1936:1;1933;1926:12;1888:52;-1:-1:-1;1959:23:1;;1808:180;-1:-1:-1;1808:180:1:o;1993:250::-;2078:1;2088:113;2102:6;2099:1;2096:13;2088:113;;;2178:11;;;2172:18;2159:11;;;2152:39;2124:2;2117:10;2088:113;;;-1:-1:-1;;2235:1:1;2217:16;;2210:27;1993:250::o;2248:271::-;2290:3;2328:5;2322:12;2355:6;2350:3;2343:19;2371:76;2440:6;2433:4;2428:3;2424:14;2417:4;2410:5;2406:16;2371:76;:::i;:::-;2501:2;2480:15;-1:-1:-1;;2476:29:1;2467:39;;;;2508:4;2463:50;;2248:271;-1:-1:-1;;2248:271:1:o;2524:220::-;2673:2;2662:9;2655:21;2636:4;2693:45;2734:2;2723:9;2719:18;2711:6;2693:45;:::i;2749:751::-;2853:6;2861;2869;2877;2930:2;2918:9;2909:7;2905:23;2901:32;2898:52;;;2946:1;2943;2936:12;2898:52;2982:9;2969:23;2959:33;;3039:2;3028:9;3024:18;3011:32;3001:42;;3094:2;3083:9;3079:18;3066:32;3117:18;3158:2;3150:6;3147:14;3144:34;;;3174:1;3171;3164:12;3144:34;3212:6;3201:9;3197:22;3187:32;;3257:7;3250:4;3246:2;3242:13;3238:27;3228:55;;3279:1;3276;3269:12;3228:55;3319:2;3306:16;3345:2;3337:6;3334:14;3331:34;;;3361:1;3358;3351:12;3331:34;3414:7;3409:2;3399:6;3396:1;3392:14;3388:2;3384:23;3380:32;3377:45;3374:65;;;3435:1;3432;3425:12;3374:65;2749:751;;;;-1:-1:-1;;3466:2:1;3458:11;;-1:-1:-1;;;2749:751:1:o;3505:127::-;3566:10;3561:3;3557:20;3554:1;3547:31;3597:4;3594:1;3587:15;3621:4;3618:1;3611:15;3637:249;3747:2;3728:13;;-1:-1:-1;;3724:27:1;3712:40;;3782:18;3767:34;;3803:22;;;3764:62;3761:88;;;3829:18;;:::i;:::-;3865:2;3858:22;-1:-1:-1;;3637:249:1:o;3891:183::-;3951:4;3984:18;3976:6;3973:30;3970:56;;;4006:18;;:::i;:::-;-1:-1:-1;4051:1:1;4047:14;4063:4;4043:25;;3891:183::o;4079:724::-;4133:5;4186:3;4179:4;4171:6;4167:17;4163:27;4153:55;;4204:1;4201;4194:12;4153:55;4240:6;4227:20;4266:4;4289:43;4329:2;4289:43;:::i;:::-;4361:2;4355:9;4373:31;4401:2;4393:6;4373:31;:::i;:::-;4439:18;;;4531:1;4527:10;;;;4515:23;;4511:32;;;4473:15;;;;-1:-1:-1;4555:15:1;;;4552:35;;;4583:1;4580;4573:12;4552:35;4619:2;4611:6;4607:15;4631:142;4647:6;4642:3;4639:15;4631:142;;;4713:17;;4701:30;;4751:12;;;;4664;;4631:142;;;-1:-1:-1;4791:6:1;4079:724;-1:-1:-1;;;;;;4079:724:1:o;4808:555::-;4850:5;4903:3;4896:4;4888:6;4884:17;4880:27;4870:55;;4921:1;4918;4911:12;4870:55;4957:6;4944:20;4983:18;4979:2;4976:26;4973:52;;;5005:18;;:::i;:::-;5054:2;5048:9;5066:67;5121:2;5102:13;;-1:-1:-1;;5098:27:1;5127:4;5094:38;5048:9;5066:67;:::i;:::-;5157:2;5149:6;5142:18;5203:3;5196:4;5191:2;5183:6;5179:15;5175:26;5172:35;5169:55;;;5220:1;5217;5210:12;5169:55;5284:2;5277:4;5269:6;5265:17;5258:4;5250:6;5246:17;5233:54;5331:1;5307:15;;;5324:4;5303:26;5296:37;;;;5311:6;4808:555;-1:-1:-1;;;4808:555:1:o;5368:943::-;5522:6;5530;5538;5546;5554;5607:3;5595:9;5586:7;5582:23;5578:33;5575:53;;;5624:1;5621;5614:12;5575:53;5647:29;5666:9;5647:29;:::i;:::-;5637:39;;5695:38;5729:2;5718:9;5714:18;5695:38;:::i;:::-;5685:48;;5784:2;5773:9;5769:18;5756:32;5807:18;5848:2;5840:6;5837:14;5834:34;;;5864:1;5861;5854:12;5834:34;5887:61;5940:7;5931:6;5920:9;5916:22;5887:61;:::i;:::-;5877:71;;6001:2;5990:9;5986:18;5973:32;5957:48;;6030:2;6020:8;6017:16;6014:36;;;6046:1;6043;6036:12;6014:36;6069:63;6124:7;6113:8;6102:9;6098:24;6069:63;:::i;:::-;6059:73;;6185:3;6174:9;6170:19;6157:33;6141:49;;6215:2;6205:8;6202:16;6199:36;;;6231:1;6228;6221:12;6199:36;;6254:51;6297:7;6286:8;6275:9;6271:24;6254:51;:::i;:::-;6244:61;;;5368:943;;;;;;;;:::o;6498:1208::-;6616:6;6624;6677:2;6665:9;6656:7;6652:23;6648:32;6645:52;;;6693:1;6690;6683:12;6645:52;6733:9;6720:23;6762:18;6803:2;6795:6;6792:14;6789:34;;;6819:1;6816;6809:12;6789:34;6857:6;6846:9;6842:22;6832:32;;6902:7;6895:4;6891:2;6887:13;6883:27;6873:55;;6924:1;6921;6914:12;6873:55;6960:2;6947:16;6982:4;7005:43;7045:2;7005:43;:::i;:::-;7077:2;7071:9;7089:31;7117:2;7109:6;7089:31;:::i;:::-;7155:18;;;7243:1;7239:10;;;;7231:19;;7227:28;;;7189:15;;;;-1:-1:-1;7267:19:1;;;7264:39;;;7299:1;7296;7289:12;7264:39;7323:11;;;;7343:148;7359:6;7354:3;7351:15;7343:148;;;7425:23;7444:3;7425:23;:::i;:::-;7413:36;;7376:12;;;;7469;;;;7343:148;;;7510:6;-1:-1:-1;;7554:18:1;;7541:32;;-1:-1:-1;;7585:16:1;;;7582:36;;;7614:1;7611;7604:12;7582:36;;7637:63;7692:7;7681:8;7670:9;7666:24;7637:63;:::i;:::-;7627:73;;;6498:1208;;;;;:::o;7711:435::-;7764:3;7802:5;7796:12;7829:6;7824:3;7817:19;7855:4;7884:2;7879:3;7875:12;7868:19;;7921:2;7914:5;7910:14;7942:1;7952:169;7966:6;7963:1;7960:13;7952:169;;;8027:13;;8015:26;;8061:12;;;;8096:15;;;;7988:1;7981:9;7952:169;;;-1:-1:-1;8137:3:1;;7711:435;-1:-1:-1;;;;;7711:435:1:o;8151:261::-;8330:2;8319:9;8312:21;8293:4;8350:56;8402:2;8391:9;8387:18;8379:6;8350:56;:::i;8810:347::-;8875:6;8883;8936:2;8924:9;8915:7;8911:23;8907:32;8904:52;;;8952:1;8949;8942:12;8904:52;8975:29;8994:9;8975:29;:::i;:::-;8965:39;;9054:2;9043:9;9039:18;9026:32;9101:5;9094:13;9087:21;9080:5;9077:32;9067:60;;9123:1;9120;9113:12;9067:60;9146:5;9136:15;;;8810:347;;;;;:::o;9162:254::-;9230:6;9238;9291:2;9279:9;9270:7;9266:23;9262:32;9259:52;;;9307:1;9304;9297:12;9259:52;9343:9;9330:23;9320:33;;9372:38;9406:2;9395:9;9391:18;9372:38;:::i;:::-;9362:48;;9162:254;;;;;:::o;9421:260::-;9489:6;9497;9550:2;9538:9;9529:7;9525:23;9521:32;9518:52;;;9566:1;9563;9556:12;9518:52;9589:29;9608:9;9589:29;:::i;:::-;9579:39;;9637:38;9671:2;9660:9;9656:18;9637:38;:::i;9686:606::-;9790:6;9798;9806;9814;9822;9875:3;9863:9;9854:7;9850:23;9846:33;9843:53;;;9892:1;9889;9882:12;9843:53;9915:29;9934:9;9915:29;:::i;:::-;9905:39;;9963:38;9997:2;9986:9;9982:18;9963:38;:::i;:::-;9953:48;;10048:2;10037:9;10033:18;10020:32;10010:42;;10099:2;10088:9;10084:18;10071:32;10061:42;;10154:3;10143:9;10139:19;10126:33;10182:18;10174:6;10171:30;10168:50;;;10214:1;10211;10204:12;10168:50;10237:49;10278:7;10269:6;10258:9;10254:22;10237:49;:::i;10297:186::-;10356:6;10409:2;10397:9;10388:7;10384:23;10380:32;10377:52;;;10425:1;10422;10415:12;10377:52;10448:29;10467:9;10448:29;:::i;10899:390::-;11058:2;11047:9;11040:21;11097:6;11092:2;11081:9;11077:18;11070:34;11154:6;11146;11141:2;11130:9;11126:18;11113:48;11210:1;11181:22;;;11205:2;11177:31;;;11170:42;;;;11273:2;11252:15;;;-1:-1:-1;;11248:29:1;11233:45;11229:54;;10899:390;-1:-1:-1;10899:390:1:o;11294:380::-;11373:1;11369:12;;;;11416;;;11437:61;;11491:4;11483:6;11479:17;11469:27;;11437:61;11544:2;11536:6;11533:14;11513:18;11510:38;11507:161;;11590:10;11585:3;11581:20;11578:1;11571:31;11625:4;11622:1;11615:15;11653:4;11650:1;11643:15;11507:161;;11294:380;;;:::o;11805:1020::-;11981:3;12010:1;12043:6;12037:13;12073:36;12099:9;12073:36;:::i;:::-;12128:1;12145:18;;;12172:133;;;;12319:1;12314:356;;;;12138:532;;12172:133;-1:-1:-1;;12205:24:1;;12193:37;;12278:14;;12271:22;12259:35;;12250:45;;;-1:-1:-1;12172:133:1;;12314:356;12345:6;12342:1;12335:17;12375:4;12420:2;12417:1;12407:16;12445:1;12459:165;12473:6;12470:1;12467:13;12459:165;;;12551:14;;12538:11;;;12531:35;12594:16;;;;12488:10;;12459:165;;;12463:3;;;12653:6;12648:3;12644:16;12637:23;;12138:532;;;;;12701:6;12695:13;12717:68;12776:8;12771:3;12764:4;12756:6;12752:17;12717:68;:::i;:::-;12801:18;;11805:1020;-1:-1:-1;;;;11805:1020:1:o;12830:127::-;12891:10;12886:3;12882:20;12879:1;12872:31;12922:4;12919:1;12912:15;12946:4;12943:1;12936:15;12962:125;13027:9;;;13048:10;;;13045:36;;;13061:18;;:::i;13092:410::-;13294:2;13276:21;;;13333:2;13313:18;;;13306:30;13372:34;13367:2;13352:18;;13345:62;-1:-1:-1;;;13438:2:1;13423:18;;13416:44;13492:3;13477:19;;13092:410::o;13917:127::-;13978:10;13973:3;13969:20;13966:1;13959:31;14009:4;14006:1;13999:15;14033:4;14030:1;14023:15;14049:135;14088:3;14109:17;;;14106:43;;14129:18;;:::i;:::-;-1:-1:-1;14176:1:1;14165:13;;14049:135::o;14957:545::-;15059:2;15054:3;15051:11;15048:448;;;15095:1;15120:5;15116:2;15109:17;15165:4;15161:2;15151:19;15235:2;15223:10;15219:19;15216:1;15212:27;15206:4;15202:38;15271:4;15259:10;15256:20;15253:47;;;-1:-1:-1;15294:4:1;15253:47;15349:2;15344:3;15340:12;15337:1;15333:20;15327:4;15323:31;15313:41;;15404:82;15422:2;15415:5;15412:13;15404:82;;;15467:17;;;15448:1;15437:13;15404:82;;15048:448;14957:545;;;:::o;15678:1352::-;15804:3;15798:10;15831:18;15823:6;15820:30;15817:56;;;15853:18;;:::i;:::-;15882:97;15972:6;15932:38;15964:4;15958:11;15932:38;:::i;:::-;15926:4;15882:97;:::i;:::-;16034:4;;16098:2;16087:14;;16115:1;16110:663;;;;16817:1;16834:6;16831:89;;;-1:-1:-1;16886:19:1;;;16880:26;16831:89;-1:-1:-1;;15635:1:1;15631:11;;;15627:24;15623:29;15613:40;15659:1;15655:11;;;15610:57;16933:81;;16080:944;;16110:663;11752:1;11745:14;;;11789:4;11776:18;;-1:-1:-1;;16146:20:1;;;16264:236;16278:7;16275:1;16272:14;16264:236;;;16367:19;;;16361:26;16346:42;;16459:27;;;;16427:1;16415:14;;;;16294:19;;16264:236;;;16268:3;16528:6;16519:7;16516:19;16513:201;;;16589:19;;;16583:26;-1:-1:-1;;16672:1:1;16668:14;;;16684:3;16664:24;16660:37;16656:42;16641:58;16626:74;;16513:201;-1:-1:-1;;;;;16760:1:1;16744:14;;;16740:22;16727:36;;-1:-1:-1;15678:1352:1:o;17940:401::-;18142:2;18124:21;;;18181:2;18161:18;;;18154:30;18220:34;18215:2;18200:18;;18193:62;-1:-1:-1;;;18286:2:1;18271:18;;18264:35;18331:3;18316:19;;17940:401::o;18346:406::-;18548:2;18530:21;;;18587:2;18567:18;;;18560:30;18626:34;18621:2;18606:18;;18599:62;-1:-1:-1;;;18692:2:1;18677:18;;18670:40;18742:3;18727:19;;18346:406::o;18757:465::-;19014:2;19003:9;18996:21;18977:4;19040:56;19092:2;19081:9;19077:18;19069:6;19040:56;:::i;:::-;19144:9;19136:6;19132:22;19127:2;19116:9;19112:18;19105:50;19172:44;19209:6;19201;19172:44;:::i;:::-;19164:52;18757:465;-1:-1:-1;;;;;18757:465:1:o;20701:827::-;-1:-1:-1;;;;;21098:15:1;;;21080:34;;21150:15;;21145:2;21130:18;;21123:43;21060:3;21197:2;21182:18;;21175:31;;;21023:4;;21229:57;;21266:19;;21258:6;21229:57;:::i;:::-;21334:9;21326:6;21322:22;21317:2;21306:9;21302:18;21295:50;21368:44;21405:6;21397;21368:44;:::i;:::-;21354:58;;21461:9;21453:6;21449:22;21443:3;21432:9;21428:19;21421:51;21489:33;21515:6;21507;21489:33;:::i;:::-;21481:41;20701:827;-1:-1:-1;;;;;;;;20701:827:1:o;21533:249::-;21602:6;21655:2;21643:9;21634:7;21630:23;21626:32;21623:52;;;21671:1;21668;21661:12;21623:52;21703:9;21697:16;21722:30;21746:5;21722:30;:::i;21787:179::-;21822:3;21864:1;21846:16;21843:23;21840:120;;;21910:1;21907;21904;21889:23;-1:-1:-1;21947:1:1;21941:8;21936:3;21932:18;21840:120;21787:179;:::o;21971:671::-;22010:3;22052:4;22034:16;22031:26;22028:39;;;21971:671;:::o;22028:39::-;22094:2;22088:9;-1:-1:-1;;22159:16:1;22155:25;;22152:1;22088:9;22131:50;22210:4;22204:11;22234:16;22269:18;22340:2;22333:4;22325:6;22321:17;22318:25;22313:2;22305:6;22302:14;22299:45;22296:58;;;22347:5;;;;;21971:671;:::o;22296:58::-;22384:6;22378:4;22374:17;22363:28;;22420:3;22414:10;22447:2;22439:6;22436:14;22433:27;;;22453:5;;;;;;21971:671;:::o;22433:27::-;22537:2;22518:16;22512:4;22508:27;22504:36;22497:4;22488:6;22483:3;22479:16;22475:27;22472:69;22469:82;;;22544:5;;;;;;21971:671;:::o;22469:82::-;22560:57;22611:4;22602:6;22594;22590:19;22586:30;22580:4;22560:57;:::i;:::-;-1:-1:-1;22633:3:1;;21971:671;-1:-1:-1;;;;;21971:671:1:o;23068:404::-;23270:2;23252:21;;;23309:2;23289:18;;;23282:30;23348:34;23343:2;23328:18;;23321:62;-1:-1:-1;;;23414:2:1;23399:18;;23392:38;23462:3;23447:19;;23068:404::o;23477:561::-;-1:-1:-1;;;;;23774:15:1;;;23756:34;;23826:15;;23821:2;23806:18;;23799:43;23873:2;23858:18;;23851:34;;;23916:2;23901:18;;23894:34;;;23736:3;23959;23944:19;;23937:32;;;23699:4;;23986:46;;24012:19;;24004:6;23986:46;:::i;:::-;23978:54;23477:561;-1:-1:-1;;;;;;;23477:561:1:o

Swarm Source

ipfs://282e08a9624beed61fe286b1d68198f3bc33bfa32d233ba95751a617fb8eae64
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.