Contract Address Details

0x5722b050f05ea665366Ed9286F238fF30e0538D5

Token
0x5722b0-0538d5
Creator
0x28130b–c2b92f at 0x4e0303–53fa5f
Balance
0 VT
Tokens
Fetching tokens...
Transactions
17,279 Transactions
Transfers
0 Transfers
Gas Used
18,046,055,433
Last Balance Update
31821600
Contract is not verified. However, we found a verified contract with the same bytecode in Blockscout DB 0x124213ac05c34e8ad3f1d2ca3084ca6f393e6b49.
All metadata displayed below is from that contract. In order to verify current contract, click Verify & Publish button
Verify & Publish
Contract name:
RegistryExtended




Optimization enabled
true
Compiler version
v0.8.4+commit.c7e474f2




Optimization runs
200
Verified at
2021-12-23T17:31:40.335670Z

Contract source code

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.3.3/contracts/utils/Context.sol



pragma solidity ^0.8.0;

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.3.3/contracts/utils/Address.sol



pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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



pragma solidity ^0.8.0;

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

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



pragma solidity ^0.8.0;


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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.3.3/contracts/token/ERC1155/IERC1155Receiver.sol



pragma solidity ^0.8.0;


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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.3.3/contracts/token/ERC1155/IERC1155.sol



pragma solidity ^0.8.0;


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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.3.3/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol



pragma solidity ^0.8.0;


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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.3.3/contracts/token/ERC1155/ERC1155.sol



pragma solidity ^0.8.0;







/**
 * @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 private _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: balance query for the zero address");
        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 {
        require(_msgSender() != operator, "ERC1155: setting approval status for self");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_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 owner nor 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: transfer caller is not owner nor 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();

        _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), 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);

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

        _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 `account`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _mint(
        address account,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(account != address(0), "ERC1155: mint to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);

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

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

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
     *
     * 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);

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

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

        address operator = _msgSender();

        _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");

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

        emit TransferSingle(operator, account, address(0), id, amount);
    }

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

        address operator = _msgSender();

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

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

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

        emit TransferBatch(operator, account, address(0), ids, amounts);
    }

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

// File: contracts/IERC1888.sol


pragma solidity 0.8.4;

// import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";


interface ERC1888 is IERC1155 {

    struct Certificate {
        uint256 topic;
        address issuer;
        bytes validityData;
        bytes data;
    }

   event IssuanceSingle(address indexed _issuer, uint256 indexed _topic, uint256 _id, uint256 _value);
   event IssuanceBatch(address indexed _issuer, uint256[] indexed _topics, uint256[] _ids, uint256[] _values);
   
   event ClaimSingle(address indexed _claimIssuer, address indexed _claimSubject, uint256 indexed _topic, uint256 _id, uint256 _value, bytes _claimData);
   event ClaimBatch(address indexed _claimIssuer, address indexed _claimSubject, uint256[] indexed _topics, uint256[] _ids, uint256[] _values, bytes[] _claimData);
   
   function issue(address _to, bytes calldata _validityData, uint256 _topic, uint256 _value, bytes calldata _data) external returns (uint256 id);
   function batchIssue(address _to, bytes[] calldata _validityData, uint256[] calldata _topics, uint256[] calldata _values, bytes[] calldata _data) external returns (uint256[] memory ids);
   
   function safeTransferAndClaimFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data, bytes calldata _claimData) external;
   function safeBatchTransferAndClaimFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data, bytes[] calldata _claimData) external;

   function claimedBalanceOf(address _owner, uint256 _id) external view returns (uint256);
   function claimedBalanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory);

   function getCertificate(uint256 _id) external view returns (address issuer, uint256 topic, bytes memory validityCall, bytes memory data);
}
// File: contracts/Registry.sol


pragma solidity 0.8.4;

// import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";



/// @title Implementation of the Transferable Certificate standard ERC-1888.
/// @dev Also complies to ERC-1155: https://eips.ethereum.org/EIPS/eip-1155.
/// @dev ** Data set to 0 because there is no meaningful check yet to be done on the data
contract Registry is ERC1155, ERC1888 {

	// Storage for the Certificate structs
	mapping(uint256 => Certificate) public certificateStorage;

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

	// Incrementing nonce, used for generating certificate IDs
    uint256 internal _latestCertificateId;

	constructor(string memory _uri) ERC1155(_uri) {
		// Trigger ERC1155 constructor
	}

	/// @notice See {IERC1888-issue}.
    /// @dev `_to` cannot be the zero address.
	function issue(address _to, bytes calldata _validityData, uint256 _topic, uint256 _value, bytes calldata _data) external override returns (uint256 id) {
		require(_to != address(0x0), "_to must be non-zero.");
		
		_validate(_msgSender(), _validityData);

		id = ++_latestCertificateId;
		ERC1155._mint(_to, id, _value, new bytes(0)); // Check **

		certificateStorage[id] = Certificate({
			topic: _topic,
			issuer: _msgSender(),
			validityData: _validityData,
			data: _data
		});

		emit IssuanceSingle(_msgSender(), _topic, id, _value);
	}

	/// @notice See {IERC1888-batchIssue}.
    /// @dev `_to` cannot be the zero address.
    /// @dev `_data`, `_values` and `_validityData` must have the same length.
	function batchIssue(address _to, bytes[] calldata _validityData, uint256[] calldata _topics, uint256[] calldata _values, bytes[] calldata _data) external override returns (uint256[] memory ids) {
		require(_to != address(0x0), "_to must be non-zero.");
		require(_data.length == _values.length, "Arrays not same length");
		require(_values.length == _validityData.length, "Arrays not same length");

		ids = new uint256[](_values.length);

		address operator = _msgSender();

		for (uint256 i = 0; i <= _values.length; i++) {
			ids[i] = i + _latestCertificateId + 1;
			_validate(operator, _validityData[i]);
		}
			
		ERC1155._mintBatch(_to, ids, _values, new bytes(0)); // Check **

		for (uint256 i = 0; i < ids.length; i++) {
			certificateStorage[ids[i]] = Certificate({
				topic: _topics[i],
				issuer: operator,
				validityData: _validityData[i],
				data: _data[i]
			});
		}

		emit IssuanceBatch(operator, _topics, ids, _values);
	}

	/// @notice Allows the issuer to mint more fungible tokens for existing ERC-188 certificates.
    /// @dev Allows batch issuing to an array of _to addresses.
    /// @dev `_to` cannot be the zero address.
	function mint(uint256 _id, address _to, uint256 _quantity) external {
		require(_to != address(0x0), "_to must be non-zero.");
		require(_quantity > 0, "_quantity must be above 0.");

		Certificate memory cert = certificateStorage[_id];
		require(_msgSender() == cert.issuer, "Not original issuer");

		ERC1155._mint(_to, _id, _quantity, new bytes(0)); // Check **
	}

	/// @notice See {IERC1888-safeTransferAndClaimFrom}.
    /// @dev `_to` cannot be the zero address.
    /// @dev `_from` has to have a balance above or equal `_value`.
	function safeTransferAndClaimFrom(
		address _from,
		address _to,
		uint256 _id,
		uint256 _value,
		bytes calldata _data,
		bytes calldata _claimData
	) external override {
		Certificate memory cert = certificateStorage[_id];

		_validate(cert.issuer,  cert.validityData);

        require(_to != address(0x0), "_to must be non-zero.");
		require(_from != address(0x0), "_from address must be non-zero.");

        require(_from == _msgSender() || ERC1155.isApprovedForAll(_from, _msgSender()), "No operator approval");
        require(ERC1155.balanceOf(_from, _id) >= _value, "_from balance less than _value");

		if (_from != _to) {
			safeTransferFrom(_from, _to, _id, _value, _data);
		}

		_burn(_to, _id, _value);

		emit ClaimSingle(_from, _to, cert.topic, _id, _value, _claimData); //_claimSubject address ??
	}

	/// @notice See {IERC1888-safeBatchTransferAndClaimFrom}.
    /// @dev `_to` and `_from` cannot be the zero addresses.
    /// @dev `_from` has to have a balance above 0.
	function safeBatchTransferAndClaimFrom(
		address _from,
		address _to,
		uint256[] calldata _ids,
		uint256[] calldata _values,
		bytes calldata _data,
		bytes[] calldata _claimData
	) external override {

        require(_to != address(0x0), "_to address must be non-zero");
		require(_from != address(0x0), "_from address must be non-zero");

        require(_ids.length == _values.length, "Arrays not same length");
		require(_values.length == _claimData.length, "Arrays not same length.");
        require(_from == _msgSender() || ERC1155.isApprovedForAll(_from, _msgSender()), "No operator approval");

		require(_ids.length > 0, "no certificates specified");

		uint256 numberOfClaims = _ids.length;

		uint256[] memory topics = new uint256[](numberOfClaims);

		for (uint256 i = 0; i < numberOfClaims; i++) {
			Certificate memory cert = certificateStorage[_ids[i]];
			_validate(cert.issuer,  cert.validityData);
			topics[i] = cert.topic;
		}

		if (_from != _to) {
			safeBatchTransferFrom(_from, _to, _ids, _values, _data);
		}

		for (uint256 i = 0; i < numberOfClaims; i++) {
			_burn(_to, _ids[i], _values[i]);
		}

		emit ClaimBatch(_from, _to, topics, _ids, _values, _claimData);
	}

	/// @notice See {IERC1888-claimedBalanceOf}.
	function claimedBalanceOf(address _owner, uint256 _id) external override view returns (uint256) {
		return claimedBalances[_id][_owner];
	}

	/// @notice See {IERC1888-claimedBalanceOfBatch}.
	function claimedBalanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external override view returns (uint256[] memory) {
        require(_owners.length == _ids.length, "owners and ids length mismatch");

        uint256[] memory batchClaimBalances = new uint256[](_owners.length);

        for (uint256 i = 0; i < _owners.length; i++) {
            batchClaimBalances[i] = this.claimedBalanceOf(_owners[i], _ids[i]);
        }

        return batchClaimBalances;
	}

	/// @notice See {IERC1888-getCertificate}.
	function getCertificate(uint256 _id) public view override returns (address issuer, uint256 topic, bytes memory validityCall, bytes memory data) {
		require(_id <= _latestCertificateId, "_id out of bounds");

		Certificate memory certificate = certificateStorage[_id];
		return (certificate.issuer, certificate.topic, certificate.validityData, certificate.data);
	}

	/// @notice Burn certificates after they've been claimed, and increase the claimed balance.
	function _burn(address _from, uint256 _id, uint256 _value) internal override {
		ERC1155._burn(_from, _id, _value);

		claimedBalances[_id][_from] = claimedBalances[_id][_from] + _value;
	}

	/// @notice Validate if the certificate is valid against an external `_verifier` contract.
	function _validate(address _verifier, bytes memory _validityData) internal view {
		(bool success, bytes memory result) = _verifier.staticcall(_validityData);

		require(success && abi.decode(result, (bool)), "Request/certificate invalid");
	}
}

// File: contracts/RegistryExtended.sol


pragma solidity 0.8.4;


/// @title Extension of the Transferable Certificate standard ERC-1888.
contract RegistryExtended is Registry {

    event TransferBatchMultiple(address indexed operator, address[] from, address[] to, uint256[] ids, uint256[] values);
    event ClaimBatchMultiple(address[] _claimIssuer, address[] _claimSubject, uint256[] indexed _topics, uint256[] _ids, uint256[] _values, bytes[] _claimData);

	constructor(string memory _uri) Registry(_uri) {
		// Trigger Registry constructor
	}

	/// @notice Similar to {IERC1888-batchIssue}, but not a part of the ERC-1888 standard.
    /// @dev Allows batch issuing to an array of _to addresses.
    /// @dev `_to` cannot be the zero addresses.
    /// @dev `_to`, `_data`, `_values`, `_topics` and `_validityData` must have the same length.
	function batchIssueMultiple(address[] calldata _to, bytes[] calldata _validityData, uint256[] calldata _topics, uint256[] calldata _values, bytes[] calldata _data) external returns (uint256[] memory ids) {
        require(_values.length > 0, "no values specified");

		require(_to.length == _data.length, "Arrays not same length");
		require(_data.length == _values.length, "Arrays not same length");
		require(_values.length == _validityData.length, "Arrays not same length");
		require(_validityData.length == _topics.length, "Arrays not same length");

		ids = new uint256[](_values.length);

		address operator = _msgSender();

		for (uint256 i = 0; i < _values.length; i++) {
			require(_to[i] != address(0x0), "_to must be non-zero.");
			ids[i] = i + _latestCertificateId + 1;
			_validate(operator, _validityData[i]);
		}
			
		for (uint256 i = 0; i < ids.length; i++) {
			ERC1155._mint(_to[i], ids[i], _values[i], _data[i]); // Check **

			certificateStorage[ids[i]] = Certificate({
				topic: _topics[i],
				issuer: operator,
				validityData: _validityData[i],
				data: _data[i]
			});
		}

		_latestCertificateId = ids[ids.length - 1];

		emit IssuanceBatch(operator, _topics, ids, _values);
	}

	/// @notice Similar to {ERC1155-safeBatchTransferFrom}, but not a part of the ERC-1155 standard.
    /// @dev Allows batch transferring to/from an array of addresses.
    function safeBatchTransferFromMultiple(
        address[] calldata _from,
        address[] calldata _to,
        uint256[] calldata _ids,
        uint256[] calldata _values,
        bytes[] calldata _data
    ) external {
        require(_from.length == _to.length, "Arrays not same length");
        require(_to.length == _ids.length, "Arrays not same length");
        require(_ids.length == _values.length, "Arrays not same length");
		require(_values.length == _data.length, "Arrays not same length.");

		for (uint256 i = 0; i < _ids.length; i++) {
            require(_from[i] != address(0x0), "_from must be non-zero.");
            require(_to[i] != address(0x0), "_to must be non-zero.");
            require(_from[i] == _msgSender() || ERC1155.isApprovedForAll(_from[i], _msgSender()), "No operator approval");
			require(ERC1155.balanceOf(_from[i], _ids[i]) >= _values[i], "Not enough balance to transfer");

            Certificate memory cert = certificateStorage[_ids[i]];

			_validate(cert.issuer,  cert.validityData);
		}

        address operator = _msgSender();

        for (uint256 i = 0; i < _ids.length; ++i) {
            _safeTransferFrom(_from[i], _to[i], _ids[i], _values[i], _data[i]);
        }

        emit TransferBatchMultiple(operator, _from, _to, _ids, _values);
    }

	/// @notice Similar to {IERC1888-safeBatchTransferAndClaimFrom}, but not a part of the ERC-1888 standard.
	/// @dev Allows batch claiming to/from an array of addresses.
	function safeBatchTransferAndClaimFromMultiple(
		address[] calldata _from,
		address[] calldata _to,
		uint256[] calldata _ids,
		uint256[] calldata _values,
		bytes[] calldata _data,
		bytes[] calldata _claimData
	) external {
        require(_ids.length > 0, "no certificates specified");

        require(_from.length == _to.length, "Arrays not same length");
        require(_to.length == _ids.length, "Arrays not same length");
        require(_ids.length == _values.length, "Arrays not same length");
		require(_values.length == _data.length, "Arrays not same length.");
		require(_data.length == _claimData.length, "Arrays not same length.");

		uint256[] memory topics = new uint256[](_ids.length);

		for (uint256 i = 0; i < _ids.length; i++) {
            require(_from[i] != address(0x0), "_from must be non-zero.");
            require(_to[i] != address(0x0), "_to must be non-zero.");
            require(_from[i] == _msgSender() || ERC1155.isApprovedForAll(_from[i], _msgSender()), "No operator approval");
			require(ERC1155.balanceOf(_from[i], _ids[i]) >= _values[i], "Not enough balance to claim");

            Certificate memory cert = certificateStorage[_ids[i]];

			_validate(cert.issuer,  cert.validityData);
		}

		for (uint256 i = 0; i < _ids.length; i++) {
			Certificate memory cert = certificateStorage[_ids[i]];
			topics[i] = cert.topic;

			if (_from[i] != _to[i]) {
            	_safeTransferFrom(_from[i], _to[i], _ids[i], _values[i], _data[i]);
			}

			_burn(_to[i], _ids[i], _values[i]);
		}

		emit ClaimBatchMultiple(_from, _to, topics, _ids, _values, _claimData);
	}
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"string","name":"_uri","internalType":"string"}]},{"type":"event","name":"ApprovalForAll","inputs":[{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"address","name":"operator","internalType":"address","indexed":true},{"type":"bool","name":"approved","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"ClaimBatch","inputs":[{"type":"address","name":"_claimIssuer","internalType":"address","indexed":true},{"type":"address","name":"_claimSubject","internalType":"address","indexed":true},{"type":"uint256[]","name":"_topics","internalType":"uint256[]","indexed":true},{"type":"uint256[]","name":"_ids","internalType":"uint256[]","indexed":false},{"type":"uint256[]","name":"_values","internalType":"uint256[]","indexed":false},{"type":"bytes[]","name":"_claimData","internalType":"bytes[]","indexed":false}],"anonymous":false},{"type":"event","name":"ClaimBatchMultiple","inputs":[{"type":"address[]","name":"_claimIssuer","internalType":"address[]","indexed":false},{"type":"address[]","name":"_claimSubject","internalType":"address[]","indexed":false},{"type":"uint256[]","name":"_topics","internalType":"uint256[]","indexed":true},{"type":"uint256[]","name":"_ids","internalType":"uint256[]","indexed":false},{"type":"uint256[]","name":"_values","internalType":"uint256[]","indexed":false},{"type":"bytes[]","name":"_claimData","internalType":"bytes[]","indexed":false}],"anonymous":false},{"type":"event","name":"ClaimSingle","inputs":[{"type":"address","name":"_claimIssuer","internalType":"address","indexed":true},{"type":"address","name":"_claimSubject","internalType":"address","indexed":true},{"type":"uint256","name":"_topic","internalType":"uint256","indexed":true},{"type":"uint256","name":"_id","internalType":"uint256","indexed":false},{"type":"uint256","name":"_value","internalType":"uint256","indexed":false},{"type":"bytes","name":"_claimData","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"IssuanceBatch","inputs":[{"type":"address","name":"_issuer","internalType":"address","indexed":true},{"type":"uint256[]","name":"_topics","internalType":"uint256[]","indexed":true},{"type":"uint256[]","name":"_ids","internalType":"uint256[]","indexed":false},{"type":"uint256[]","name":"_values","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"IssuanceSingle","inputs":[{"type":"address","name":"_issuer","internalType":"address","indexed":true},{"type":"uint256","name":"_topic","internalType":"uint256","indexed":true},{"type":"uint256","name":"_id","internalType":"uint256","indexed":false},{"type":"uint256","name":"_value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TransferBatch","inputs":[{"type":"address","name":"operator","internalType":"address","indexed":true},{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256[]","name":"ids","internalType":"uint256[]","indexed":false},{"type":"uint256[]","name":"values","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"TransferBatchMultiple","inputs":[{"type":"address","name":"operator","internalType":"address","indexed":true},{"type":"address[]","name":"from","internalType":"address[]","indexed":false},{"type":"address[]","name":"to","internalType":"address[]","indexed":false},{"type":"uint256[]","name":"ids","internalType":"uint256[]","indexed":false},{"type":"uint256[]","name":"values","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"TransferSingle","inputs":[{"type":"address","name":"operator","internalType":"address","indexed":true},{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"id","internalType":"uint256","indexed":false},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"URI","inputs":[{"type":"string","name":"value","internalType":"string","indexed":false},{"type":"uint256","name":"id","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"balanceOfBatch","inputs":[{"type":"address[]","name":"accounts","internalType":"address[]"},{"type":"uint256[]","name":"ids","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256[]","name":"ids","internalType":"uint256[]"}],"name":"batchIssue","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"bytes[]","name":"_validityData","internalType":"bytes[]"},{"type":"uint256[]","name":"_topics","internalType":"uint256[]"},{"type":"uint256[]","name":"_values","internalType":"uint256[]"},{"type":"bytes[]","name":"_data","internalType":"bytes[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256[]","name":"ids","internalType":"uint256[]"}],"name":"batchIssueMultiple","inputs":[{"type":"address[]","name":"_to","internalType":"address[]"},{"type":"bytes[]","name":"_validityData","internalType":"bytes[]"},{"type":"uint256[]","name":"_topics","internalType":"uint256[]"},{"type":"uint256[]","name":"_values","internalType":"uint256[]"},{"type":"bytes[]","name":"_data","internalType":"bytes[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"topic","internalType":"uint256"},{"type":"address","name":"issuer","internalType":"address"},{"type":"bytes","name":"validityData","internalType":"bytes"},{"type":"bytes","name":"data","internalType":"bytes"}],"name":"certificateStorage","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"claimedBalanceOf","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"uint256","name":"_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"claimedBalanceOfBatch","inputs":[{"type":"address[]","name":"_owners","internalType":"address[]"},{"type":"uint256[]","name":"_ids","internalType":"uint256[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"claimedBalances","inputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"issuer","internalType":"address"},{"type":"uint256","name":"topic","internalType":"uint256"},{"type":"bytes","name":"validityCall","internalType":"bytes"},{"type":"bytes","name":"data","internalType":"bytes"}],"name":"getCertificate","inputs":[{"type":"uint256","name":"_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isApprovedForAll","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"address","name":"operator","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"id","internalType":"uint256"}],"name":"issue","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"bytes","name":"_validityData","internalType":"bytes"},{"type":"uint256","name":"_topic","internalType":"uint256"},{"type":"uint256","name":"_value","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mint","inputs":[{"type":"uint256","name":"_id","internalType":"uint256"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_quantity","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeBatchTransferAndClaimFrom","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256[]","name":"_ids","internalType":"uint256[]"},{"type":"uint256[]","name":"_values","internalType":"uint256[]"},{"type":"bytes","name":"_data","internalType":"bytes"},{"type":"bytes[]","name":"_claimData","internalType":"bytes[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeBatchTransferAndClaimFromMultiple","inputs":[{"type":"address[]","name":"_from","internalType":"address[]"},{"type":"address[]","name":"_to","internalType":"address[]"},{"type":"uint256[]","name":"_ids","internalType":"uint256[]"},{"type":"uint256[]","name":"_values","internalType":"uint256[]"},{"type":"bytes[]","name":"_data","internalType":"bytes[]"},{"type":"bytes[]","name":"_claimData","internalType":"bytes[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeBatchTransferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256[]","name":"ids","internalType":"uint256[]"},{"type":"uint256[]","name":"amounts","internalType":"uint256[]"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeBatchTransferFromMultiple","inputs":[{"type":"address[]","name":"_from","internalType":"address[]"},{"type":"address[]","name":"_to","internalType":"address[]"},{"type":"uint256[]","name":"_ids","internalType":"uint256[]"},{"type":"uint256[]","name":"_values","internalType":"uint256[]"},{"type":"bytes[]","name":"_data","internalType":"bytes[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeTransferAndClaimFrom","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_id","internalType":"uint256"},{"type":"uint256","name":"_value","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"},{"type":"bytes","name":"_claimData","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeTransferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"id","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setApprovalForAll","inputs":[{"type":"address","name":"operator","internalType":"address"},{"type":"bool","name":"approved","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"interfaceId","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"uri","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]}]
            

Deployed ByteCode

Verify & Publish
0x608060405234801561001057600080fd5b50600436106101365760003560e01c80638673605a116100b8578063ba688a941161007c578063ba688a94146102c9578063c48238b0146102dc578063c5308dd814610307578063d6878ffb1461031a578063e985e9c51461033d578063f242432a1461037957600080fd5b80638673605a1461026a5780638838a9d71461027d5780638ed8707514610290578063a22cb465146102a3578063b93bbaa0146102b657600080fd5b80634e1273f4116100ff5780634e1273f4146101ee57806351640fee1461020e578063543d526d14610231578063760c6caf14610244578063836a10401461025757600080fd5b8062fdd58e1461013b57806301ffc9a7146101615780630e89341c146101845780632eb2c2d6146101a45780633ebbaaa5146101b9575b600080fd5b61014e61014936600461447e565b61038c565b6040519081526020015b60405180910390f35b61017461016f3660046147ef565b610423565b6040519015158152602001610158565b610197610192366004614827565b610475565b6040516101589190614d17565b6101b76101b2366004614140565b610509565b005b61014e6101c736600461447e565b60009081526004602090815260408083206001600160a01b03949094168352929052205490565b6102016101fc366004614709565b6105a0565b6040516101589190614ca6565b61022161021c366004614827565b610701565b6040516101589493929190614b4d565b61014e61023f3660046143ee565b6108ca565b6101b761025236600461405e565b610aed565b6101b7610265366004614879565b611056565b6102016102783660046142e7565b61129c565b61020161028b3660046144a7565b6116e8565b61020161029e3660046146a1565b611c63565b6101b76102b13660046143b8565b611e3a565b6101b76102c43660046144a7565b611f11565b6101b76102d736600461456b565b61254a565b61014e6102ea366004614857565b600460209081526000928352604080842090915290825290205481565b6101b76103153660046141e5565b612e9e565b61032d610328366004614827565b6131e1565b6040516101589493929190614f4e565b61017461034b36600461402c565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205460ff1690565b6101b7610387366004614285565b613324565b60006001600160a01b0383166103fd5760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b60648201526084015b60405180910390fd5b506000908152602081815260408083206001600160a01b03949094168352929052205490565b60006001600160e01b03198216636cdb3d1360e11b148061045457506001600160e01b031982166303a24d0760e21b145b8061046f57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600280546104849061505a565b80601f01602080910402602001604051908101604052809291908181526020018280546104b09061505a565b80156104fd5780601f106104d2576101008083540402835291602001916104fd565b820191906000526020600020905b8154815290600101906020018083116104e057829003601f168201915b50505050509050919050565b6001600160a01b0385163314806105255750610525853361034b565b61058c5760405162461bcd60e51b815260206004820152603260248201527f455243313135353a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b60648201526084016103f4565b61059985858585856133ab565b5050505050565b606081518351146106055760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016103f4565b600083516001600160401b0381111561062e57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610657578160200160208202803683370190505b50905060005b84518110156106f9576106be85828151811061068957634e487b7160e01b600052603260045260246000fd5b60200260200101518583815181106106b157634e487b7160e01b600052603260045260246000fd5b602002602001015161038c565b8282815181106106de57634e487b7160e01b600052603260045260246000fd5b60209081029190910101526106f2816150c1565b905061065d565b509392505050565b60008060608060055485111561074d5760405162461bcd60e51b81526020600482015260116024820152705f6964206f7574206f6620626f756e647360781b60448201526064016103f4565b600085815260036020908152604080832081516080810183528154815260018201546001600160a01b03169381019390935260028101805491928401916107939061505a565b80601f01602080910402602001604051908101604052809291908181526020018280546107bf9061505a565b801561080c5780601f106107e15761010080835404028352916020019161080c565b820191906000526020600020905b8154815290600101906020018083116107ef57829003601f168201915b505050505081526020016003820180546108259061505a565b80601f01602080910402602001604051908101604052809291908181526020018280546108519061505a565b801561089e5780601f106108735761010080835404028352916020019161089e565b820191906000526020600020905b81548152906001019060200180831161088157829003601f168201915b505050919092525050506020810151815160408301516060909301519199909850919650945092505050565b60006001600160a01b0388166108f25760405162461bcd60e51b81526004016103f490614f1f565b6109323388888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061356392505050565b600560008154610941906150c1565b9182905550905061098188828660005b6040519080825280601f01601f19166020018201604052801561097b576020820181803683370190505b5061362b565b60405180608001604052808681526020016109993390565b6001600160a01b0316815260200188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250604080516020601f87018190048102820181019092528581529181019190869086908190840183828082843760009201829052509390945250508381526003602090815260409182902084518155848201516001820180546001600160a01b0319166001600160a01b03909216919091179055918401518051929350610a6f9260028501929190910190613dec565b5060608201518051610a8b916003840191602090910190613dec565b5090505084610a973390565b6001600160a01b03167f19fdba3b3fa810260206510aa7278c70ea23c0d104195bed67bfb27a3d82fbfe8387604051610ada929190918252602082015260400190565b60405180910390a3979650505050505050565b6001600160a01b038916610b435760405162461bcd60e51b815260206004820152601c60248201527f5f746f2061646472657373206d757374206265206e6f6e2d7a65726f0000000060448201526064016103f4565b6001600160a01b038a16610b995760405162461bcd60e51b815260206004820152601e60248201527f5f66726f6d2061646472657373206d757374206265206e6f6e2d7a65726f000060448201526064016103f4565b868514610bb85760405162461bcd60e51b81526004016103f490614e66565b848114610bd75760405162461bcd60e51b81526004016103f490614e2f565b6001600160a01b038a16331480610bf35750610bf38a3361034b565b610c0f5760405162461bcd60e51b81526004016103f490614d72565b86610c585760405162461bcd60e51b81526020600482015260196024820152781b9bc818d95c9d1a599a58d85d195cc81cdc1958da599a5959603a1b60448201526064016103f4565b866000816001600160401b03811115610c8157634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610caa578160200160208202803683370190505b50905060005b82811015610e9a576000600360008d8d85818110610cde57634e487b7160e01b600052603260045260246000fd5b6020908102929092013583525081810192909252604090810160002081516080810183528154815260018201546001600160a01b0316938101939093526002810180549192840191610d2f9061505a565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5b9061505a565b8015610da85780601f10610d7d57610100808354040283529160200191610da8565b820191906000526020600020905b815481529060010190602001808311610d8b57829003601f168201915b50505050508152602001600382018054610dc19061505a565b80601f0160208091040260200160405190810160405280929190818152602001828054610ded9061505a565b8015610e3a5780601f10610e0f57610100808354040283529160200191610e3a565b820191906000526020600020905b815481529060010190602001808311610e1d57829003601f168201915b5050505050815250509050610e5781602001518260400151613563565b8060000151838381518110610e7c57634e487b7160e01b600052603260045260246000fd5b60209081029190910101525080610e92816150c1565b915050610cb0565b508a6001600160a01b03168c6001600160a01b031614610f6857610f688c8c8c8c80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508b8b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020601f8f018190048102820181019092528d815292508d91508c908190840183828082843760009201919091525061050992505050565b60005b82811015610fdc57610fca8c8c8c84818110610f9757634e487b7160e01b600052603260045260246000fd5b905060200201358b8b85818110610fbe57634e487b7160e01b600052603260045260246000fd5b905060200201356136fb565b80610fd4816150c1565b915050610f6b565b5080604051610feb9190614a58565b60405180910390208b6001600160a01b03168d6001600160a01b03167f61a69d58bffe77be60879031f7e6d3d17fab9c88a681899a549d20ae8a39f8d08d8d8d8d8b8b60405161104096959493929190614c5d565b60405180910390a4505050505050505050505050565b6001600160a01b03821661107c5760405162461bcd60e51b81526004016103f490614f1f565b600081116110cc5760405162461bcd60e51b815260206004820152601a60248201527f5f7175616e74697479206d7573742062652061626f766520302e00000000000060448201526064016103f4565b600083815260036020908152604080832081516080810183528154815260018201546001600160a01b03169381019390935260028101805491928401916111129061505a565b80601f016020809104026020016040519081016040528092919081815260200182805461113e9061505a565b801561118b5780601f106111605761010080835404028352916020019161118b565b820191906000526020600020905b81548152906001019060200180831161116e57829003601f168201915b505050505081526020016003820180546111a49061505a565b80601f01602080910402602001604051908101604052809291908181526020018280546111d09061505a565b801561121d5780601f106111f25761010080835404028352916020019161121d565b820191906000526020600020905b81548152906001019060200180831161120057829003601f168201915b505050505081525050905080602001516001600160a01b031661123d3390565b6001600160a01b0316146112895760405162461bcd60e51b81526020600482015260136024820152722737ba1037b934b3b4b730b61034b9b9bab2b960691b60448201526064016103f4565b6112968385846000610951565b50505050565b60606001600160a01b038a166112c45760405162461bcd60e51b81526004016103f490614f1f565b8184146112e35760405162461bcd60e51b81526004016103f490614e66565b8388146113025760405162461bcd60e51b81526004016103f490614e66565b836001600160401b0381111561132857634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611351578160200160208202803683370190505b5090503360005b8581116114255760055461136c9082614fff565b611377906001614fff565b83828151811061139757634e487b7160e01b600052603260045260246000fd5b602002602001018181525050611413828c8c848181106113c757634e487b7160e01b600052603260045260246000fd5b90506020028101906113d99190614f98565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061356392505050565b8061141d816150c1565b915050611358565b506114948b8388888080602002602001604051908101604052809392919081815260200183836020028082843760009201829052509250611464915050565b6040519080825280601f01601f19166020018201604052801561148e576020820181803683370190505b50613760565b60005b825181101561167c5760405180608001604052808a8a848181106114cb57634e487b7160e01b600052603260045260246000fd5b905060200201358152602001836001600160a01b031681526020018c8c8481811061150657634e487b7160e01b600052603260045260246000fd5b90506020028101906115189190614f98565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200186868481811061157257634e487b7160e01b600052603260045260246000fd5b90506020028101906115849190614f98565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509390945250508551600392508690859081106115e057634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000820151816000015560208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506040820151816002019080519060200190611649929190613dec565b5060608201518051611665916003840191602090910190613dec565b509050508080611674906150c1565b915050611497565b50878760405161168d929190614a2e565b6040518091039020816001600160a01b03167f4337762bcc37db59d5eea698d442c9782e625db731704f4f83ed376a09b64e6c8489896040516116d293929190614cb9565b60405180910390a3509998505050505050505050565b60608361172d5760405162461bcd60e51b81526020600482015260136024820152721b9bc81d985b1d595cc81cdc1958da599a5959606a1b60448201526064016103f4565b89821461174c5760405162461bcd60e51b81526004016103f490614e66565b81841461176b5760405162461bcd60e51b81526004016103f490614e66565b83881461178a5760405162461bcd60e51b81526004016103f490614e66565b8786146117a95760405162461bcd60e51b81526004016103f490614e66565b836001600160401b038111156117cf57634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156117f8578160200160208202803683370190505b5090503360005b858110156118df5760008d8d8381811061182957634e487b7160e01b600052603260045260246000fd5b905060200201602081019061183e919061400b565b6001600160a01b031614156118655760405162461bcd60e51b81526004016103f490614f1f565b6005546118729082614fff565b61187d906001614fff565b83828151811061189d57634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506118cd828c8c848181106113c757634e487b7160e01b600052603260045260246000fd5b806118d7816150c1565b9150506117ff565b5060005b8251811015611bbb576119df8d8d8381811061190f57634e487b7160e01b600052603260045260246000fd5b9050602002016020810190611924919061400b565b84838151811061194457634e487b7160e01b600052603260045260246000fd5b602002602001015189898581811061196c57634e487b7160e01b600052603260045260246000fd5b9050602002013588888681811061199357634e487b7160e01b600052603260045260246000fd5b90506020028101906119a59190614f98565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061362b92505050565b60405180608001604052808a8a84818110611a0a57634e487b7160e01b600052603260045260246000fd5b905060200201358152602001836001600160a01b031681526020018c8c84818110611a4557634e487b7160e01b600052603260045260246000fd5b9050602002810190611a579190614f98565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001868684818110611ab157634e487b7160e01b600052603260045260246000fd5b9050602002810190611ac39190614f98565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250939094525050855160039250869085908110611b1f57634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000820151816000015560208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506040820151816002019080519060200190611b88929190613dec565b5060608201518051611ba4916003840191602090910190613dec565b509050508080611bb3906150c1565b9150506118e3565b508160018351611bcb9190615017565b81518110611be957634e487b7160e01b600052603260045260246000fd5b60200260200101516005819055508787604051611c07929190614a2e565b6040518091039020816001600160a01b03167f4337762bcc37db59d5eea698d442c9782e625db731704f4f83ed376a09b64e6c848989604051611c4c93929190614cb9565b60405180910390a3509a9950505050505050505050565b6060838214611cb45760405162461bcd60e51b815260206004820152601e60248201527f6f776e65727320616e6420696473206c656e677468206d69736d61746368000060448201526064016103f4565b6000846001600160401b03811115611cdc57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611d05578160200160208202803683370190505b50905060005b85811015611e305730633ebbaaa5888884818110611d3957634e487b7160e01b600052603260045260246000fd5b9050602002016020810190611d4e919061400b565b878785818110611d6e57634e487b7160e01b600052603260045260246000fd5b6040516001600160e01b031960e087901b1681526001600160a01b039094166004850152602002919091013560248301525060440160206040518083038186803b158015611dbb57600080fd5b505afa158015611dcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df3919061483f565b828281518110611e1357634e487b7160e01b600052603260045260246000fd5b602090810291909101015280611e28816150c1565b915050611d0b565b5095945050505050565b336001600160a01b0383161415611ea55760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016103f4565b3360008181526001602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b888714611f305760405162461bcd60e51b81526004016103f490614e66565b868514611f4f5760405162461bcd60e51b81526004016103f490614e66565b848314611f6e5760405162461bcd60e51b81526004016103f490614e66565b828114611f8d5760405162461bcd60e51b81526004016103f490614e2f565b60005b858110156123a95760008b8b83818110611fba57634e487b7160e01b600052603260045260246000fd5b9050602002016020810190611fcf919061400b565b6001600160a01b031614156120205760405162461bcd60e51b81526020600482015260176024820152762fb33937b69036bab9ba103132903737b716bd32b9379760491b60448201526064016103f4565b600089898381811061204257634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612057919061400b565b6001600160a01b0316141561207e5760405162461bcd60e51b81526004016103f490614f1f565b338b8b8381811061209f57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906120b4919061400b565b6001600160a01b0316148061210257506121028b8b838181106120e757634e487b7160e01b600052603260045260246000fd5b90506020020160208101906120fc919061400b565b3361034b565b61211e5760405162461bcd60e51b81526004016103f490614d72565b84848281811061213e57634e487b7160e01b600052603260045260246000fd5b905060200201356121a98c8c8481811061216857634e487b7160e01b600052603260045260246000fd5b905060200201602081019061217d919061400b565b89898581811061219d57634e487b7160e01b600052603260045260246000fd5b9050602002013561038c565b10156121f75760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420656e6f7567682062616c616e636520746f207472616e73666572000060448201526064016103f4565b60006003600089898581811061221d57634e487b7160e01b600052603260045260246000fd5b6020908102929092013583525081810192909252604090810160002081516080810183528154815260018201546001600160a01b031693810193909352600281018054919284019161226e9061505a565b80601f016020809104026020016040519081016040528092919081815260200182805461229a9061505a565b80156122e75780601f106122bc576101008083540402835291602001916122e7565b820191906000526020600020905b8154815290600101906020018083116122ca57829003601f168201915b505050505081526020016003820180546123009061505a565b80601f016020809104026020016040519081016040528092919081815260200182805461232c9061505a565b80156123795780601f1061234e57610100808354040283529160200191612379565b820191906000526020600020905b81548152906001019060200180831161235c57829003601f168201915b505050505081525050905061239681602001518260400151613563565b50806123a1816150c1565b915050611f90565b503360005b868110156124ed576124dd8c8c838181106123d957634e487b7160e01b600052603260045260246000fd5b90506020020160208101906123ee919061400b565b8b8b8481811061240e57634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612423919061400b565b8a8a8581811061244357634e487b7160e01b600052603260045260246000fd5b9050602002013589898681811061246a57634e487b7160e01b600052603260045260246000fd5b9050602002013588888781811061249157634e487b7160e01b600052603260045260246000fd5b90506020028101906124a39190614f98565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506138c792505050565b6124e6816150c1565b90506123ae565b50806001600160a01b03167f9a17c5980bc0d14e313aaa844f04cd0ee291f743df00bf06337a3ce1db563be48c8c8c8c8c8c8c8c604051612535989796959493929190614b86565b60405180910390a25050505050505050505050565b866125935760405162461bcd60e51b81526020600482015260196024820152781b9bc818d95c9d1a599a58d85d195cc81cdc1958da599a5959603a1b60448201526064016103f4565b8a89146125b25760405162461bcd60e51b81526004016103f490614e66565b8887146125d15760405162461bcd60e51b81526004016103f490614e66565b8685146125f05760405162461bcd60e51b81526004016103f490614e66565b84831461260f5760405162461bcd60e51b81526004016103f490614e2f565b82811461262e5760405162461bcd60e51b81526004016103f490614e2f565b6000876001600160401b0381111561265657634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561267f578160200160208202803683370190505b50905060005b88811015612a775760008e8e838181106126af57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906126c4919061400b565b6001600160a01b031614156127155760405162461bcd60e51b81526020600482015260176024820152762fb33937b69036bab9ba103132903737b716bd32b9379760491b60448201526064016103f4565b60008c8c8381811061273757634e487b7160e01b600052603260045260246000fd5b905060200201602081019061274c919061400b565b6001600160a01b031614156127735760405162461bcd60e51b81526004016103f490614f1f565b338e8e8381811061279457634e487b7160e01b600052603260045260246000fd5b90506020020160208101906127a9919061400b565b6001600160a01b031614806127dc57506127dc8e8e838181106120e757634e487b7160e01b600052603260045260246000fd5b6127f85760405162461bcd60e51b81526004016103f490614d72565b87878281811061281857634e487b7160e01b600052603260045260246000fd5b905060200201356128778f8f8481811061284257634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612857919061400b565b8c8c8581811061219d57634e487b7160e01b600052603260045260246000fd5b10156128c55760405162461bcd60e51b815260206004820152601b60248201527f4e6f7420656e6f7567682062616c616e636520746f20636c61696d000000000060448201526064016103f4565b6000600360008c8c858181106128eb57634e487b7160e01b600052603260045260246000fd5b6020908102929092013583525081810192909252604090810160002081516080810183528154815260018201546001600160a01b031693810193909352600281018054919284019161293c9061505a565b80601f01602080910402602001604051908101604052809291908181526020018280546129689061505a565b80156129b55780601f1061298a576101008083540402835291602001916129b5565b820191906000526020600020905b81548152906001019060200180831161299857829003601f168201915b505050505081526020016003820180546129ce9061505a565b80601f01602080910402602001604051908101604052809291908181526020018280546129fa9061505a565b8015612a475780601f10612a1c57610100808354040283529160200191612a47565b820191906000526020600020905b815481529060010190602001808311612a2a57829003601f168201915b5050505050815250509050612a6481602001518260400151613563565b5080612a6f816150c1565b915050612685565b5060005b88811015612e2f576000600360008c8c85818110612aa957634e487b7160e01b600052603260045260246000fd5b6020908102929092013583525081810192909252604090810160002081516080810183528154815260018201546001600160a01b0316938101939093526002810180549192840191612afa9061505a565b80601f0160208091040260200160405190810160405280929190818152602001828054612b269061505a565b8015612b735780601f10612b4857610100808354040283529160200191612b73565b820191906000526020600020905b815481529060010190602001808311612b5657829003601f168201915b50505050508152602001600382018054612b8c9061505a565b80601f0160208091040260200160405190810160405280929190818152602001828054612bb89061505a565b8015612c055780601f10612bda57610100808354040283529160200191612c05565b820191906000526020600020905b815481529060010190602001808311612be857829003601f168201915b50505050508152505090508060000151838381518110612c3557634e487b7160e01b600052603260045260246000fd5b6020026020010181815250508c8c83818110612c6157634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612c76919061400b565b6001600160a01b03168f8f84818110612c9f57634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612cb4919061400b565b6001600160a01b031614612d9d57612d9d8f8f84818110612ce557634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612cfa919061400b565b8e8e85818110612d1a57634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612d2f919061400b565b8d8d86818110612d4f57634e487b7160e01b600052603260045260246000fd5b905060200201358c8c87818110612d7657634e487b7160e01b600052603260045260246000fd5b905060200201358b8b8881811061249157634e487b7160e01b600052603260045260246000fd5b612e1c8d8d84818110612dc057634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612dd5919061400b565b8c8c85818110612df557634e487b7160e01b600052603260045260246000fd5b905060200201358b8b86818110610fbe57634e487b7160e01b600052603260045260246000fd5b5080612e27816150c1565b915050612a7b565b5080604051612e3e9190614a58565b60405180910390207f5fb4aec6c096dfcae3899570b7e14f9743bb4b1801780db6d8a9c4ffe21aaaac8e8e8e8e8e8e8e8e8c8c604051612e879a99989796959493929190614be6565b60405180910390a250505050505050505050505050565b600086815260036020908152604080832081516080810183528154815260018201546001600160a01b0316938101939093526002810180549192840191612ee49061505a565b80601f0160208091040260200160405190810160405280929190818152602001828054612f109061505a565b8015612f5d5780601f10612f3257610100808354040283529160200191612f5d565b820191906000526020600020905b815481529060010190602001808311612f4057829003601f168201915b50505050508152602001600382018054612f769061505a565b80601f0160208091040260200160405190810160405280929190818152602001828054612fa29061505a565b8015612fef5780601f10612fc457610100808354040283529160200191612fef565b820191906000526020600020905b815481529060010190602001808311612fd257829003601f168201915b505050505081525050905061300c81602001518260400151613563565b6001600160a01b0388166130325760405162461bcd60e51b81526004016103f490614f1f565b6001600160a01b0389166130885760405162461bcd60e51b815260206004820152601f60248201527f5f66726f6d2061646472657373206d757374206265206e6f6e2d7a65726f2e0060448201526064016103f4565b6001600160a01b0389163314806130a457506130a4893361034b565b6130c05760405162461bcd60e51b81526004016103f490614d72565b856130cb8a8961038c565b10156131195760405162461bcd60e51b815260206004820152601e60248201527f5f66726f6d2062616c616e6365206c657373207468616e205f76616c7565000060448201526064016103f4565b876001600160a01b0316896001600160a01b031614613175576131758989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061332492505050565b6131808888886136fb565b8060000151886001600160a01b03168a6001600160a01b03167fde6a12665e566ee081354e23cd8474944fb8e89a25b46f2f9b50d378e7e536088a8a88886040516131ce9493929190614f78565b60405180910390a4505050505050505050565b60036020526000908152604090208054600182015460028301805492936001600160a01b03909216926132139061505a565b80601f016020809104026020016040519081016040528092919081815260200182805461323f9061505a565b801561328c5780601f106132615761010080835404028352916020019161328c565b820191906000526020600020905b81548152906001019060200180831161326f57829003601f168201915b5050505050908060030180546132a19061505a565b80601f01602080910402602001604051908101604052809291908181526020018280546132cd9061505a565b801561331a5780601f106132ef5761010080835404028352916020019161331a565b820191906000526020600020905b8154815290600101906020018083116132fd57829003601f168201915b5050505050905084565b6001600160a01b0385163314806133405750613340853361034b565b61339e5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201526808185c1c1c9bdd995960ba1b60648201526084016103f4565b61059985858585856138c7565b81518351146133cc5760405162461bcd60e51b81526004016103f490614e96565b6001600160a01b0384166133f25760405162461bcd60e51b81526004016103f490614da0565b3360005b84518110156134f557600085828151811061342157634e487b7160e01b600052603260045260246000fd5b60200260200101519050600085838151811061344d57634e487b7160e01b600052603260045260246000fd5b602090810291909101810151600084815280835260408082206001600160a01b038e16835290935291909120549091508181101561349d5760405162461bcd60e51b81526004016103f490614de5565b6000838152602081815260408083206001600160a01b038e8116855292528083208585039055908b168252812080548492906134da908490614fff565b92505081905550505050806134ee906150c1565b90506133f6565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051613545929190614ce9565b60405180910390a461355b8187878787876139e4565b505050505050565b600080836001600160a01b03168360405161357e9190614a8e565b600060405180830381855afa9150503d80600081146135b9576040519150601f19603f3d011682016040523d82523d6000602084013e6135be565b606091505b50915091508180156135df5750808060200190518101906135df91906147d3565b6112965760405162461bcd60e51b815260206004820152601b60248201527f526571756573742f636572746966696361746520696e76616c6964000000000060448201526064016103f4565b6001600160a01b0384166136515760405162461bcd60e51b81526004016103f490614ede565b3361366b8160008761366288613b4f565b61059988613b4f565b6000848152602081815260408083206001600160a01b03891684529091528120805485929061369b908490614fff565b909155505060408051858152602081018590526001600160a01b0380881692600092918516917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461059981600087878787613ba8565b613706838383613c72565b60008281526004602090815260408083206001600160a01b0387168452909152902054613734908290614fff565b60009283526004602090815260408085206001600160a01b039096168552949052929091209190915550565b6001600160a01b0384166137865760405162461bcd60e51b81526004016103f490614ede565b81518351146137a75760405162461bcd60e51b81526004016103f490614e96565b3360005b845181101561385f578381815181106137d457634e487b7160e01b600052603260045260246000fd5b60200260200101516000808784815181106137ff57634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b0316815260200190815260200160002060008282546138479190614fff565b90915550819050613857816150c1565b9150506137ab565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516138b0929190614ce9565b60405180910390a4610599816000878787876139e4565b6001600160a01b0384166138ed5760405162461bcd60e51b81526004016103f490614da0565b336138fd81878761366288613b4f565b6000848152602081815260408083206001600160a01b038a1684529091529020548381101561393e5760405162461bcd60e51b81526004016103f490614de5565b6000858152602081815260408083206001600160a01b038b811685529252808320878503905590881682528120805486929061397b908490614fff565b909155505060408051868152602081018690526001600160a01b03808916928a821692918616917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46139db828888888888613ba8565b50505050505050565b6001600160a01b0384163b1561355b5760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190613a289089908990889088908890600401614aaa565b602060405180830381600087803b158015613a4257600080fd5b505af1925050508015613a72575060408051601f3d908101601f19168201909252613a6f9181019061480b565b60015b613b1f57613a7e615108565b806308c379a01415613ab85750613a93615120565b80613a9e5750613aba565b8060405162461bcd60e51b81526004016103f49190614d17565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e20455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016103f4565b6001600160e01b0319811663bc197c8160e01b146139db5760405162461bcd60e51b81526004016103f490614d2a565b60408051600180825281830190925260609160009190602080830190803683370190505090508281600081518110613b9757634e487b7160e01b600052603260045260246000fd5b602090810291909101015292915050565b6001600160a01b0384163b1561355b5760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e6190613bec9089908990889088908890600401614b08565b602060405180830381600087803b158015613c0657600080fd5b505af1925050508015613c36575060408051601f3d908101601f19168201909252613c339181019061480b565b60015b613c4257613a7e615108565b6001600160e01b0319811663f23a6e6160e01b146139db5760405162461bcd60e51b81526004016103f490614d2a565b6001600160a01b038316613cd45760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b60648201526084016103f4565b33613d0481856000613ce587613b4f565b613cee87613b4f565b5050604080516020810190915260009052505050565b6000838152602081815260408083206001600160a01b038816845290915290205482811015613d815760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b60648201526084016103f4565b6000848152602081815260408083206001600160a01b03898116808652918452828520888703905582518981529384018890529092908616917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a45050505050565b828054613df89061505a565b90600052602060002090601f016020900481019282613e1a5760008555613e60565b82601f10613e3357805160ff1916838001178555613e60565b82800160010185558215613e60579182015b82811115613e60578251825591602001919060010190613e45565b50613e6c929150613e70565b5090565b5b80821115613e6c5760008155600101613e71565b80356001600160a01b0381168114613e9c57600080fd5b919050565b60008083601f840112613eb2578182fd5b5081356001600160401b03811115613ec8578182fd5b6020830191508360208260051b8501011115613ee357600080fd5b9250929050565b600082601f830112613efa578081fd5b81356020613f0782614fdc565b604051613f148282615095565b8381528281019150858301600585901b87018401881015613f33578586fd5b855b85811015613f5157813584529284019290840190600101613f35565b5090979650505050505050565b60008083601f840112613f6f578182fd5b5081356001600160401b03811115613f85578182fd5b602083019150836020828501011115613ee357600080fd5b600082601f830112613fad578081fd5b81356001600160401b03811115613fc657613fc66150f2565b604051613fdd601f8301601f191660200182615095565b818152846020838601011115613ff1578283fd5b816020850160208301379081016020019190915292915050565b60006020828403121561401c578081fd5b61402582613e85565b9392505050565b6000806040838503121561403e578081fd5b61404783613e85565b915061405560208401613e85565b90509250929050565b60008060008060008060008060008060c08b8d03121561407c578586fd5b6140858b613e85565b995061409360208c01613e85565b985060408b01356001600160401b03808211156140ae578788fd5b6140ba8e838f01613ea1565b909a50985060608d01359150808211156140d2578788fd5b6140de8e838f01613ea1565b909850965060808d01359150808211156140f6578586fd5b6141028e838f01613f5e565b909650945060a08d013591508082111561411a578384fd5b506141278d828e01613ea1565b915080935050809150509295989b9194979a5092959850565b600080600080600060a08688031215614157578081fd5b61416086613e85565b945061416e60208701613e85565b935060408601356001600160401b0380821115614189578283fd5b61419589838a01613eea565b945060608801359150808211156141aa578283fd5b6141b689838a01613eea565b935060808801359150808211156141cb578283fd5b506141d888828901613f9d565b9150509295509295909350565b60008060008060008060008060c0898b031215614200578384fd5b61420989613e85565b975061421760208a01613e85565b9650604089013595506060890135945060808901356001600160401b0380821115614240578586fd5b61424c8c838d01613f5e565b909650945060a08b0135915080821115614264578384fd5b506142718b828c01613f5e565b999c989b5096995094979396929594505050565b600080600080600060a0868803121561429c578283fd5b6142a586613e85565b94506142b360208701613e85565b9350604086013592506060860135915060808601356001600160401b038111156142db578182fd5b6141d888828901613f9d565b600080600080600080600080600060a08a8c031215614304578283fd5b61430d8a613e85565b985060208a01356001600160401b0380821115614328578485fd5b6143348d838e01613ea1565b909a50985060408c013591508082111561434c578485fd5b6143588d838e01613ea1565b909850965060608c0135915080821115614370578485fd5b61437c8d838e01613ea1565b909650945060808c0135915080821115614394578384fd5b506143a18c828d01613ea1565b915080935050809150509295985092959850929598565b600080604083850312156143ca578182fd5b6143d383613e85565b915060208301356143e3816151a9565b809150509250929050565b600080600080600080600060a0888a031215614408578081fd5b61441188613e85565b965060208801356001600160401b038082111561442c578283fd5b6144388b838c01613f5e565b909850965060408a0135955060608a0135945060808a013591508082111561445e578283fd5b5061446b8a828b01613f5e565b989b979a50959850939692959293505050565b60008060408385031215614490578182fd5b61449983613e85565b946020939093013593505050565b60008060008060008060008060008060a08b8d0312156144c5578384fd5b8a356001600160401b03808211156144db578586fd5b6144e78e838f01613ea1565b909c509a5060208d01359150808211156144ff578586fd5b61450b8e838f01613ea1565b909a50985060408d0135915080821115614523578586fd5b61452f8e838f01613ea1565b909850965060608d0135915080821115614547578586fd5b6145538e838f01613ea1565b909650945060808d013591508082111561411a578384fd5b60008060008060008060008060008060008060c08d8f03121561458c578586fd5b6001600160401b038d3511156145a0578586fd5b6145ad8e8e358f01613ea1565b909c509a506001600160401b0360208e013511156145c9578586fd5b6145d98e60208f01358f01613ea1565b909a5098506001600160401b0360408e013511156145f5578586fd5b6146058e60408f01358f01613ea1565b90985096506001600160401b0360608e01351115614621578586fd5b6146318e60608f01358f01613ea1565b90965094506001600160401b0360808e0135111561464d578081fd5b61465d8e60808f01358f01613ea1565b90945092506001600160401b0360a08e01351115614679578081fd5b6146898e60a08f01358f01613ea1565b81935080925050509295989b509295989b509295989b565b600080600080604085870312156146b6578182fd5b84356001600160401b03808211156146cc578384fd5b6146d888838901613ea1565b909650945060208701359150808211156146f0578384fd5b506146fd87828801613ea1565b95989497509550505050565b6000806040838503121561471b578182fd5b82356001600160401b0380821115614731578384fd5b818501915085601f830112614744578384fd5b8135602061475182614fdc565b60405161475e8282615095565b8381528281019150858301600585901b870184018b101561477d578889fd5b8896505b848710156147a65761479281613e85565b835260019690960195918301918301614781565b50965050860135925050808211156147bc578283fd5b506147c985828601613eea565b9150509250929050565b6000602082840312156147e4578081fd5b8151614025816151a9565b600060208284031215614800578081fd5b8135614025816151ba565b60006020828403121561481c578081fd5b8151614025816151ba565b600060208284031215614838578081fd5b5035919050565b600060208284031215614850578081fd5b5051919050565b60008060408385031215614869578182fd5b8235915061405560208401613e85565b60008060006060848603121561488d578081fd5b8335925061489d60208501613e85565b9150604084013590509250925092565b81835260006020808501945082825b858110156148e8576001600160a01b036148d583613e85565b16875295820195908201906001016148bc565b509495945050505050565b60008383855260208086019550808560051b83010184845b87811015613f5157848303601f19018952813536889003601e19018112614930578687fd5b870180356001600160401b03811115614947578788fd5b803603891315614955578788fd5b61496285828885016149d9565b9a86019a945050509083019060010161490b565b81835260006001600160fb1b0383111561498e578081fd5b8260051b80836020870137939093016020019283525090919050565b6000815180845260208085019450808401835b838110156148e8578151875295820195908201906001016149bd565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60008151808452614a1a81602086016020860161502e565b601f01601f19169290920160200192915050565b60006001600160fb1b03831115614a43578081fd5b8260051b808584379190910190815292915050565b815160009082906020808601845b83811015614a8257815185529382019390820190600101614a66565b50929695505050505050565b60008251614aa081846020870161502e565b9190910192915050565b6001600160a01b0386811682528516602082015260a060408201819052600090614ad6908301866149aa565b8281036060840152614ae881866149aa565b90508281036080840152614afc8185614a02565b98975050505050505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a060808201819052600090614b4290830184614a02565b979650505050505050565b60018060a01b0385168152836020820152608060408201526000614b746080830185614a02565b8281036060840152614b428185614a02565b608081526000614b9a608083018a8c6148ad565b8281036020840152614bad81898b6148ad565b90508281036040840152614bc2818789614976565b90508281036060840152614bd7818587614976565b9b9a5050505050505050505050565b60a081526000614bfa60a083018c8e6148ad565b8281036020840152614c0d818b8d6148ad565b90508281036040840152614c2281898b614976565b90508281036060840152614c37818789614976565b90508281036080840152614c4c8185876148f3565b9d9c50505050505050505050505050565b606081526000614c7160608301888a614976565b8281036020840152614c84818789614976565b90508281036040840152614c998185876148f3565b9998505050505050505050565b60208152600061402560208301846149aa565b604081526000614ccc60408301866149aa565b8281036020840152614cdf818587614976565b9695505050505050565b604081526000614cfc60408301856149aa565b8281036020840152614d0e81856149aa565b95945050505050565b6020815260006140256020830184614a02565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b602080825260149082015273139bc81bdc195c985d1bdc88185c1c1c9bdd985b60621b604082015260600190565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b60208082526017908201527f417272617973206e6f742073616d65206c656e6774682e000000000000000000604082015260600190565b602080825260169082015275082e4e4c2f2e640dcdee840e6c2daca40d8cadccee8d60531b604082015260600190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b6020808252601590820152742fba379036bab9ba103132903737b716bd32b9379760591b604082015260600190565b8481526001600160a01b0384166020820152608060408201819052600090614b7490830185614a02565b848152836020820152606060408201526000614cdf6060830184866149d9565b6000808335601e19843603018112614fae578283fd5b8301803591506001600160401b03821115614fc7578283fd5b602001915036819003821315613ee357600080fd5b60006001600160401b03821115614ff557614ff56150f2565b5060051b60200190565b60008219821115615012576150126150dc565b500190565b600082821015615029576150296150dc565b500390565b60005b83811015615049578181015183820152602001615031565b838111156112965750506000910152565b600181811c9082168061506e57607f821691505b6020821081141561508f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8201601f191681016001600160401b03811182821017156150ba576150ba6150f2565b6040525050565b60006000198214156150d5576150d56150dc565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600060033d111561511d57600481823e5160e01c5b90565b600060443d101561512e5790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561515d57505050505090565b82850191508151818111156151755750505050505090565b843d870101602082850101111561518f5750505050505090565b61519e60208286010187615095565b509095945050505050565b80151581146151b757600080fd5b50565b6001600160e01b0319811681146151b757600080fdfea26469706673582212201fcc2a6d641dda60e8c8e8c5f20ec97063420fba03f88e88fe47cdf69e4ec9a264736f6c63430008040033