ETH Price: $3,403.19 (-1.21%)
Gas: 5 Gwei

Token

Fock Store (FCKS)
 

Overview

Max Total Supply

0 FCKS

Holders

108

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
0x0037e222bd8f047a453b9ed0b04067c95e56bcb3
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
FockStore

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 7 of 17: FockStore.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

/*****************************************************************************************************************************************************
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@........................................................................................................................@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@........................................................................................................................@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@........................................................................................................................@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@.........................................................................................................................@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@...................++++++++++++++++-......-+++++++++++++..........+++++++++++++-..........................................@@@@@@@@@@@@@@
@@@@@@@@@@@@....................#@@@@@@@@@@@@@@@@%:....:%@@@@@@@@@@@@@*........*@@@@@@@@@@@@@%:....%%%.............+%#....................@@@@@@@@@@@@
@@@@@@@@@@@....................*@@@@@@@@@@@@@@@@@@-....@@@@@@@@@@@@@@@@+......+@@@@@@@@@@@@@@@@....@@@............=@@%......................@@@@@@@@@@
@@@@@@@@@.....................*@@@@@@@@@@@@@@@@@@%:..-@@@@@@@@@@@@@@@@@@+....+@@@@@@@@@@@@@@@@@@-..@@@@..........=@@%:.......................@@@@@@@@@
@@@@@@@@.....................*@@@================:..-%@@#=========+@@@@@@+..+@@@@@%+=========#@@%-.@@@@.........+@@%-.........................@@@@@@@@
@@@@@@@......................@@@-...................@@@%...........+@@@@@@=*@@@@@@+...........%@@=.@@@@........=@@@=...........................@@@@@@@
@@@@@@.......................@@@:...................@@@%...........+@@@@@@**@@@@@@+............%%-.@@@@.......=@@@*.............................@@@@@@
@@@@@........................@@@:...................@@@%...........+@@@@@@**@@@@@%-................@@@@......=@@@*...............................@@@@@
@@@@@........................@@@*...................@@@%...........+@@@@@@**@@@@@#.................@@@@.....+@@@+................................@@@@@
@@@@.........................@@@@%..................@@@%............#@@@@@**@@@@@..................@@@@#...%@@@*..................................@@@@
@@@@.........................@@@@@@@@@@@@@@@@@@@@@:.@@@%.............#@@@@**@@@@+..................@@@@@@@@@@@@@@@@@@-............................@@@@
@@@@.........................@@@@@@@@@@@@@@@@@@@@@-.@@@%..............*@@@**@@@*...................@@@@@@@@@@@@@@@@@@@-...........................@@@@
@@@@.........................@@@@@@@@@@@@@@@@@@@@@-.@@@%..............-@@@**@@@-...................@@@@@@@@@@@@@@@@@@@@-..........................@@@@
@@@:.........................@@@@@@@@@@@@@@@@@@@#...@@@%..............-@@@**@@@-...................@@@@@@@@@@@@@@@@@@@@@:..........................@@@
@@@..........................@@@@@@%................@@@%..............-@@@**@@@-...................@@@@@@@...........#@@@..........................@@@
@@@..........................@@@@@@-................@@@%..............-@@@**@@@-...................@@@@@@@...........:@@@=.........................@@@
@@@..........................@@@@@@-................@@@%..............-@@@**@@@-...................@@@@@@@...........:@@@*.........................@@@
@@@..........................@@@@@@-................@@@%..............=@@@**@@@-..............:@@=.@@@@@@@...........:@@@*.........................@@@
@@@..........................@@@@@@-................#@@@-............=%@@#.=@@@*.............-@@@=.@@@@@@@...........:@@@*.........................@@@
@@@..........................@@@@@@-................:#@@%############@@@#:..-@@@#############%@@#:.@@@@@@@...........:@@@*..........................@@
@@@..........................@@@@@@-..................@@@@@@@@@@@@@@@@@#:....-@@@@@@@@@@@@@@@@@@...@@@@@@-...........:@@@-..........................@@
@@@..........................%@@@@@-...................%@@@@@@@@@@@@@@#:......=@@@@@@@@@@@@@@@%....%@@@@%:...........:%@%...........................@@
@@@...........................+%#+-....................:+%@@@@@@@@@@%+:........=+@@@@@@@%@@@%+:....:+#@+-.............-+............................@@
@@@............................::........................:----------:............------:::--:........:-.............................................@@
@@@.................................................................................................................................................@@
@@@.................................................................................................................................................@@
@@@.................................................................................................................................................@@
@@@.............................#%%%%%%%%%%=...%%%%%%%%%%%%%%%%%=...*%%%%%%%%%%-....:%%%%%%%%%%%+.........:%%%%%%%%%%%%%%..........................@@@
@@@............................#@@@@@@@@@@@@-..@@@@@@@@@@@@@@@@@=..+@@@@@@@@@@@@:...@@@@@@@@@@@@@+.......:@@@@@@@@@@@@@@@-.........................@@@
@@@...........................*@@@@@@@@@@@@@@-.*#@@@@@@@@@@@@@@%-.+@@@@@@@@@@@@@@-..@@@@@@@@@@@@@@+.....-@@@@@@@@@@@@@@@*..........................@@@
@@@..........................#@@===========%@%-.:=====@@@@=====-.*@@+========@@@@@-.@@@=========*@@*...-%@@@@===========...........................@@@
@@@..........................@@=............-@-.......@@@=......+@@*.........-@@@@@:@@@:........=@@%...-@@@@@......................................@@@
@@@@.........................@@=......................@@@-......*@@*.........:@@@@@:@@@:........=@@%...-@@@@@.....................................@@@@
@@@@.........................@@#......................@@@*......*@@*.........:@@@@@:@@@:........=@@%...-@@@@@.....................................@@@@
@@@@.........................@@@%.....................@@@@%.....*@@*..........*@@@@:@@@%*......#%@@%...-@@@@@%#********-..........................@@@@
@@@@.........................@@@@@@@@@@@@@@@..........@@@@@=....*@@*...........#@@@:@@@@@@@@@@@@@@@%...-@@@@@@@@@@@@@@@@@.........................@@@@
@@@@.........................@@@@@@@@@@@@@@@@:........@@@@@#....*@@*............@@@:@@@@@@@@@@@@@@@%:..-@@@@@@@@@@@@@@@@@=........................@@@@
@@@@@........................===========@@@@@%:.......@@@@@#....*@@*............@@@:@@@@@@@=======@@%:.-@@@%=============........................@@@@@
@@@@@...................................:@@@@@@.......@@@@@#....*@@*............@@@:@@@@@*:.......:@@@.-@@@:.....................................@@@@@
@@@@@@@..................................=@@@@@.......@@@@@#....*@@*............@@@:@@@@@+.........-@@.-@@@....................................@@@@@@@
@@@@@@@......................==:.........=@@@@@.......@@@@@#....*@@*............@@@:@@@@@+.........-@@.-@@@....................................@@@@@@@
@@@@@@@@.....................@@%:........%@@@@+.......@@@@@#....:@@%:..........+@@*.@@@@@+.........-@@.-@@@...................................@@@@@@@@
@@@@@@@@@....................:@@@@@@@@@@@@@@@*........@@@@@#......@@@@@@@@@@@@@@@#..@@@@@+.........-@@..*@@@@@@@@@@@@@@@.....................@@@@@@@@@
@@@@@@@@@@@...................-@@@@@@@@@@@@@*.........#@@@@#......:%@@@@@@@@@@@@#...@@@@@+.........-@@...*@@@@@@@@@@@@@@@..................@@@@@@@@@@@
@@@@@@@@@@@@...................-@@@@@@@@@@@*...........*@@@=.......-%@@@@@@@@@@*....*@@@@-.........:#*....*@@@@@@@@@@@@@@.................@@@@@@@@@@@@
@@@@@@@@@@@@@@..................-----------.............---.........:----------......---:...........:......--------------...............@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@........................................................................................................................@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@........................................................................................................................@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@........................................................................................................................@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@.......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@......................................................................................................................@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
*****************************************************************************************************************************************************/

import "./ERC1155.sol";
import "./Ownable.sol";
import "./SafeMath.sol";
import "./Strings.sol";
import "./ECDSA.sol";
import "./ERC2981.sol";
import "./ReentrancyGuard.sol";

contract FockStore is ERC1155, Ownable, ReentrancyGuard, ERC2981 {
    using Strings for uint256;
    using SafeMath for uint256;
    using ECDSA for bytes32;

    struct Utility {
        uint256 utilityId;
        string name;
        uint256 totalSupply;
        uint256 maxSupply;
        address contractAddress;
    } 

    // Events
    event TokenMinted(address owner, uint256 utilityId, uint256 quantity);
    event TokenClaimed(address owner, uint256 utilityId);

    mapping(bytes => bool) public signatureUsed;

    mapping(uint256 => Utility) public utilities;

    // Define the signer wallet
    address private signer;

    // Define if market is active
    bool public marketIsActive = true;

    // Define if Claim is active
    bool public claimIsActive = true;

    // Base URI
    string private baseURI;

    uint256 public maxUtilityId = 0;

    string public name;
    string public symbol;
    string public baseExtension = ".json";

    /**
	 * Validate if an address is a contract
	 */
	function isContract(address _addr) internal view returns (bool) {
		uint256 size;
		assembly {
			size := extcodesize(_addr)
		}
		return size > 0;
	}

    /**
     * Contract constructor
     */
    constructor(string memory _name, string memory _symbol, address _signer, string memory _baseURI) ERC1155(_baseURI) {
        name = _name;
        symbol = _symbol;
        signer = _signer;
        setBaseURI(_baseURI);

        _setDefaultRoyalty(msg.sender, 500);
    }

    /*
     * Set the signer wallet
     */
    function setSigner(address _signer) public onlyOwner {
        signer = _signer;
    }

    /*
     * Pause market if active, make active if paused
     */
    function setMarketState(bool _newState) public onlyOwner {
        marketIsActive = _newState;
    }

    /*
     * Pause claim if active, make active if paused
     */
    function setClaimState(bool _newState) public onlyOwner {
        claimIsActive = _newState;
    }

    /**
     * Set Max supply for an utility
     */
    function setUtility(uint256 _utilityId, string memory _name, uint256 _maxSupply, address _contractAddress) public onlyOwner {
        maxUtilityId = maxUtilityId.add(1);
        utilities[_utilityId].utilityId = _utilityId;
        utilities[_utilityId].name = _name;
        utilities[_utilityId].maxSupply = _maxSupply;
        utilities[_utilityId].contractAddress = _contractAddress;
    }

    /**
     * Set Max supply for an utility
     */
    function setMaxSupply(uint256 _utilityId, uint256 _max) public onlyOwner {
        utilities[_utilityId].maxSupply = _max;
    }

    /**
     * Set Contract Address for an utility
     */
    function setUtilityContract(uint256 _utilityId, address _contractAddress) public onlyOwner {
        utilities[_utilityId].contractAddress = _contractAddress;
    }

    /**
     * Set the utility name
     */
    function setUtilityName(uint256 _utilityId, string memory _name) public onlyOwner {
        utilities[_utilityId].name = _name;
    }

    /**
     * Set max utilityId available
     */
    function setMaxUtilityId(uint256 _newUtilityId) public onlyOwner {
        maxUtilityId = _newUtilityId;
    }

    /**
     * Get utility supply
     */
    function getUtility(uint256 _utilityId) public view returns (Utility memory) {
        require(isValidUtility(_utilityId), 'Invalid utility id');

        return utilities[_utilityId];
    }

    /**
     * @dev Changes the base URI if we want to move things in the future (Callable by owner only)
     */
    function setBaseURI(string memory _baseURI) onlyOwner public {
        baseURI = _baseURI;
    }

    /**
     * Uri for utilities
     */
    function uri(uint256 _utilityId) public view override returns (string memory)
    {
        require(isValidUtility(_utilityId), "URI requested for invalid token");

        return
            bytes(baseURI).length > 0
                ? string(abi.encodePacked(baseURI, _utilityId.toString(), baseExtension))
                : baseURI;
    }

    /**
     * Withdraw
     */
    function withdraw() public onlyOwner {
        require(address(this).balance > 0, "No balance to withdraw");

        uint balance = address(this).balance;
        payable(msg.sender).transfer(balance);
    }

    /**
     * Set Royalty
     */
    function setDefaultRoyalty(address receiver, uint96 feeNumerator) public onlyOwner {
        _setDefaultRoyalty(receiver, feeNumerator);
    }

    /**
     * Supports Interface
     */
    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override (ERC1155, ERC2981)
        returns (bool)
    {
        return ERC1155.supportsInterface(interfaceId) || ERC2981.supportsInterface(interfaceId);
    }

    /**
     * Is valid a utility
     */
    function isValidUtility(uint256 _utilityId) public view returns(bool) {
        return (_utilityId > 0 && _utilityId <= maxUtilityId);
    }

    /**
     * Is valid sign
     */
    function isValidSign(
            address _wallet,
            uint _utilityId, 
            uint _qty, 
            string memory _nonce,
            bytes memory _signature
    ) public view returns (bool) {
        bytes32 hash = keccak256(abi.encodePacked(_wallet, _utilityId, _qty, _nonce));
        bytes32 message = ECDSA.toEthSignedMessageHash(hash);
        address receivedAddress = ECDSA.recover(message, _signature);

        return receivedAddress != address(0) && receivedAddress == signer;
    }

    /**
     * Mint utilities
     */
    function mint(uint _utilityId, uint _qty, string memory _nonce, bytes memory _signature) external nonReentrant {
        require(marketIsActive, "Mint is not available right now");
        require(isValidUtility(_utilityId) && utilities[_utilityId].maxSupply > 0, "utilityId is not valid");
        require(!signatureUsed[_signature], "Signature has already been used");
        require(utilities[_utilityId].totalSupply.add(_qty) <= utilities[_utilityId].maxSupply, "Qty tokens would exceed max supply");

        address destAddress = msg.sender;

        // Caller is an external contract
        if (utilities[_utilityId].contractAddress != address(0)) {
            require(isContract(msg.sender) && utilities[_utilityId].contractAddress == msg.sender, 'Sender is not a contract.');
            // tx.origin is the user's wallet
            destAddress = tx.origin;
        }

        require(isValidSign(destAddress, _utilityId, _qty, _nonce, _signature), "Signature is not valid");

        signatureUsed[_signature] = true;
        utilities[_utilityId].totalSupply = utilities[_utilityId].totalSupply.add(_qty);
        _mint(destAddress, _utilityId, _qty, '');

        emit TokenMinted(destAddress, _utilityId, _qty);
    }

    /**
    * Claim utility
    */
    function claim(uint _utilityId) external nonReentrant {
        require(claimIsActive, 'Claim is not active right now');
        require(balanceOf(msg.sender, _utilityId) > 0, "Balance must be greater than Zero");
        
        super._burn(msg.sender, _utilityId, 1);

		emit TokenClaimed(msg.sender, _utilityId);
    }
}

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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

File 3 of 17: ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "./Strings.sol";

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

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

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

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

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

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

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

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

        return (signer, RecoverError.NoError);
    }

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

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

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

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

File 4 of 17: ERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC1155/ERC1155.sol)

pragma solidity ^0.8.0;

import "./IERC1155.sol";
import "./IERC1155Receiver.sol";
import "./IERC1155MetadataURI.sol";
import "./Address.sol";
import "./Context.sol";
import "./ERC165.sol";

/**
 * @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: address zero is not a valid owner");
        return _balances[id][account];
    }

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

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

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

        return batchBalances;
    }

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

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

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

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

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

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

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

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

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

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

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

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

        address operator = _msgSender();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        address operator = _msgSender();

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

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

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

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

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

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

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

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

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

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

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

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

        address operator = _msgSender();

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

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

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

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

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

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

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

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

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

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

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

        return array;
    }
}

File 5 of 17: ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 6 of 17: ERC2981.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

        return (royalty.receiver, royaltyAmount);
    }

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

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

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

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

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

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

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

File 8 of 17: IERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

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

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

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

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

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

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

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

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

File 9 of 17: IERC1155MetadataURI.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)

pragma solidity ^0.8.0;

import "./IERC1155.sol";

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

File 10 of 17: IERC1155Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

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

pragma solidity ^0.8.0;

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

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

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 13 of 17: Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 14 of 17: Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "./Context.sol";

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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

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

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

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

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

File 15 of 17: ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

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

File 16 of 17: SafeMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

File 17 of 17: Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

import "./Math.sol";

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

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

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

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

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_signer","type":"address"},{"internalType":"string","name":"_baseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"utilityId","type":"uint256"}],"name":"TokenClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"utilityId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"TokenMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_utilityId","type":"uint256"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_utilityId","type":"uint256"}],"name":"getUtility","outputs":[{"components":[{"internalType":"uint256","name":"utilityId","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"address","name":"contractAddress","type":"address"}],"internalType":"struct FockStore.Utility","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"uint256","name":"_utilityId","type":"uint256"},{"internalType":"uint256","name":"_qty","type":"uint256"},{"internalType":"string","name":"_nonce","type":"string"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"isValidSign","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_utilityId","type":"uint256"}],"name":"isValidUtility","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxUtilityId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_utilityId","type":"uint256"},{"internalType":"uint256","name":"_qty","type":"uint256"},{"internalType":"string","name":"_nonce","type":"string"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_newState","type":"bool"}],"name":"setClaimState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_newState","type":"bool"}],"name":"setMarketState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_utilityId","type":"uint256"},{"internalType":"uint256","name":"_max","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newUtilityId","type":"uint256"}],"name":"setMaxUtilityId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_utilityId","type":"uint256"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"uint256","name":"_maxSupply","type":"uint256"},{"internalType":"address","name":"_contractAddress","type":"address"}],"name":"setUtility","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_utilityId","type":"uint256"},{"internalType":"address","name":"_contractAddress","type":"address"}],"name":"setUtilityContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_utilityId","type":"uint256"},{"internalType":"string","name":"_name","type":"string"}],"name":"setUtilityName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"signatureUsed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_utilityId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"utilities","outputs":[{"internalType":"uint256","name":"utilityId","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"address","name":"contractAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6009805461ffff60a01b191661010160a01b1790556000600b5560c06040526005608090815264173539b7b760d91b60a052600e906200004090826200036e565b503480156200004e57600080fd5b5060405162003718380380620037188339810160408190526200007191620004e9565b806200007d81620000ea565b506200008933620000fc565b6001600455600c6200009c85826200036e565b50600d620000ab84826200036e565b50600980546001600160a01b0319166001600160a01b038416179055620000d2816200014e565b620000e0336101f462000166565b505050506200059c565b6002620000f882826200036e565b5050565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b620001586200026b565b600a620000f882826200036e565b6127106001600160601b0382161115620001da5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084015b60405180910390fd5b6001600160a01b038216620002325760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401620001d1565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600555565b6003546001600160a01b03163314620002c75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620001d1565b565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620002f457607f821691505b6020821081036200031557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200036957600081815260208120601f850160051c81016020861015620003445750805b601f850160051c820191505b81811015620003655782815560010162000350565b5050505b505050565b81516001600160401b038111156200038a576200038a620002c9565b620003a2816200039b8454620002df565b846200031b565b602080601f831160018114620003da5760008415620003c15750858301515b600019600386901b1c1916600185901b17855562000365565b600085815260208120601f198616915b828110156200040b57888601518255948401946001909101908401620003ea565b50858210156200042a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600082601f8301126200044c57600080fd5b81516001600160401b0380821115620004695762000469620002c9565b604051601f8301601f19908116603f01168101908282118183101715620004945762000494620002c9565b81604052838152602092508683858801011115620004b157600080fd5b600091505b83821015620004d55785820183015181830184015290820190620004b6565b600093810190920192909252949350505050565b600080600080608085870312156200050057600080fd5b84516001600160401b03808211156200051857600080fd5b62000526888389016200043a565b955060208701519150808211156200053d57600080fd5b6200054b888389016200043a565b604088015190955091506001600160a01b03821682146200056b57600080fd5b6060870151919350808211156200058157600080fd5b5062000590878288016200043a565b91505092959194509250565b61316c80620005ac6000396000f3fe608060405234801561001057600080fd5b506004361061021b5760003560e01c80635c7c1a8e11610125578063bb10c829116100ad578063dc2140551161007c578063dc214055146104cd578063e6308717146104e0578063e985e9c5146104f3578063f242432a1461052f578063f2fde38b1461054257600080fd5b8063bb10c82914610471578063bb5b65081461049f578063c08485b7146104b2578063c6682862146104c557600080fd5b80638cc58df4116100f45780638cc58df4146104155780638da5cb5b1461042857806395d89b41146104435780639a2bee911461044b578063a22cb4651461045e57600080fd5b80635c7c1a8e146103de5780636c19e783146103f15780636dbad77814610404578063715018a61461040d57600080fd5b8063379607f5116101a857806348a8f3451161017757806348a8f345146103705780634b014e28146103845780634e1273f4146103975780635303f68c146103b757806355f804b3146103cb57600080fd5b8063379607f51461032f57806337da577c146103425780633ccfd60b146103555780634225cc231461035d57600080fd5b80630e89341c116101ef5780630e89341c1461029357806319234769146102a65780632a55205a146102c65780632d4a2146146102f85780632eb2c2d61461031c57600080fd5b8062fdd58e1461022057806301ffc9a71461024657806304634d8d1461026957806306fdde031461027e575b600080fd5b61023361022e3660046123f2565b610555565b6040519081526020015b60405180910390f35b610259610254366004612432565b6105ee565b604051901515815260200161023d565b61027c61027736600461244f565b610608565b005b61028661061e565b60405161023d91906124e2565b6102866102a13660046124f5565b6106ac565b6102b96102b43660046124f5565b6107dd565b60405161023d919061250e565b6102d96102d4366004612566565b61094a565b604080516001600160a01b03909316835260208301919091520161023d565b61030b6103063660046124f5565b6109f8565b60405161023d959493929190612588565b61027c61032a366004612710565b610aba565b61027c61033d3660046124f5565b610b06565b61027c610350366004612566565b610c1c565b61027c610c39565b61027c61036b3660046127b9565b610cb9565b60095461025990600160a01b900460ff1681565b61027c6103923660046127f5565b610cf2565b6103aa6103a5366004612810565b610d18565b60405161023d9190612915565b60095461025990600160a81b900460ff1681565b61027c6103d9366004612928565b610e41565b6102596103ec366004612964565b610e55565b61027c6103ff3660046129bb565b610f22565b610233600b5481565b61027c610f4c565b6102596104233660046124f5565b610f60565b6003546040516001600160a01b03909116815260200161023d565b610286610f75565b61027c6104593660046129d6565b610f82565b61027c61046c366004612a12565b610faa565b61025961047f366004612928565b805160208183018101805160078252928201919093012091525460ff1681565b61027c6104ad3660046124f5565b610fb5565b61027c6104c03660046127f5565b610fc2565b610286610fe8565b61027c6104db366004612a3c565b610ff5565b61027c6104ee366004612ab2565b611374565b610259610501366004612b12565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205460ff1690565b61027c61053d366004612b3c565b6113e7565b61027c6105503660046129bb565b61142c565b60006001600160a01b0383166105c55760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b60648201526084015b60405180910390fd5b506000818152602081815260408083206001600160a01b03861684529091529020545b92915050565b60006105f9826114a2565b806105e857506105e8826114f2565b610610611517565b61061a8282611571565b5050565b600c805461062b90612ba0565b80601f016020809104026020016040519081016040528092919081815260200182805461065790612ba0565b80156106a45780601f10610679576101008083540402835291602001916106a4565b820191906000526020600020905b81548152906001019060200180831161068757829003601f168201915b505050505081565b60606106b782610f60565b6107035760405162461bcd60e51b815260206004820152601f60248201527f5552492072657175657374656420666f7220696e76616c696420746f6b656e0060448201526064016105bc565b6000600a805461071290612ba0565b9050116107a957600a805461072690612ba0565b80601f016020809104026020016040519081016040528092919081815260200182805461075290612ba0565b801561079f5780601f106107745761010080835404028352916020019161079f565b820191906000526020600020905b81548152906001019060200180831161078257829003601f168201915b50505050506105e8565b600a6107b48361166e565b600e6040516020016107c893929190612c4d565b60405160208183030381529060405292915050565b6108186040518060a001604052806000815260200160608152602001600081526020016000815260200160006001600160a01b031681525090565b61082182610f60565b6108625760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a59081d5d1a5b1a5d1e481a5960721b60448201526064016105bc565b600860008381526020019081526020016000206040518060a00160405290816000820154815260200160018201805461089a90612ba0565b80601f01602080910402602001604051908101604052809291908181526020018280546108c690612ba0565b80156109135780601f106108e857610100808354040283529160200191610913565b820191906000526020600020905b8154815290600101906020018083116108f657829003601f168201915b505050918352505060028201546020820152600382015460408201526004909101546001600160a01b031660609091015292915050565b60008281526006602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925282916109bf5750604080518082019091526005546001600160a01b0381168252600160a01b90046001600160601b031660208201525b6020810151600090612710906109de906001600160601b031687612c96565b6109e89190612cad565b91519350909150505b9250929050565b60086020526000908152604090208054600182018054919291610a1a90612ba0565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4690612ba0565b8015610a935780601f10610a6857610100808354040283529160200191610a93565b820191906000526020600020905b815481529060010190602001808311610a7657829003601f168201915b5050505060028301546003840154600490940154929390929091506001600160a01b031685565b6001600160a01b038516331480610ad65750610ad68533610501565b610af25760405162461bcd60e51b81526004016105bc90612ccf565b610aff8585858585611700565b5050505050565b610b0e6118dd565b600954600160a81b900460ff16610b675760405162461bcd60e51b815260206004820152601d60248201527f436c61696d206973206e6f7420616374697665207269676874206e6f7700000060448201526064016105bc565b6000610b733383610555565b11610bca5760405162461bcd60e51b815260206004820152602160248201527f42616c616e6365206d7573742062652067726561746572207468616e205a65726044820152606f60f81b60648201526084016105bc565b610bd633826001611936565b60408051338152602081018390527fe42df0d9493dfd0d7f69902c895b94c190a53e8c27876a86f45e7c997d9d8f7c910160405180910390a1610c196001600455565b50565b610c24611517565b60009182526008602052604090912060030155565b610c41611517565b60004711610c8a5760405162461bcd60e51b81526020600482015260166024820152754e6f2062616c616e636520746f20776974686472617760501b60448201526064016105bc565b6040514790339082156108fc029083906000818181858888f1935050505015801561061a573d6000803e3d6000fd5b610cc1611517565b60009182526008602052604090912060040180546001600160a01b0319166001600160a01b03909216919091179055565b610cfa611517565b60098054911515600160a81b0260ff60a81b19909216919091179055565b60608151835114610d7d5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016105bc565b600083516001600160401b03811115610d9857610d986125c7565b604051908082528060200260200182016040528015610dc1578160200160208202803683370190505b50905060005b8451811015610e3957610e0c858281518110610de557610de5612d1d565b6020026020010151858381518110610dff57610dff612d1d565b6020026020010151610555565b828281518110610e1e57610e1e612d1d565b6020908102919091010152610e3281612d33565b9050610dc7565b509392505050565b610e49611517565b600a61061a8282612d92565b60008086868686604051602001610e6f9493929190612e51565b6040516020818303038152906040528051906020012090506000610ee0826040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000610eee8286611ab7565b90506001600160a01b03811615801590610f1557506009546001600160a01b038281169116145b9998505050505050505050565b610f2a611517565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b610f54611517565b610f5e6000611ad3565b565b600080821180156105e8575050600b54101590565b600d805461062b90612ba0565b610f8a611517565b6000828152600860205260409020600101610fa58282612d92565b505050565b61061a338383611b25565b610fbd611517565b600b55565b610fca611517565b60098054911515600160a01b0260ff60a01b19909216919091179055565b600e805461062b90612ba0565b610ffd6118dd565b600954600160a01b900460ff166110565760405162461bcd60e51b815260206004820152601f60248201527f4d696e74206973206e6f7420617661696c61626c65207269676874206e6f770060448201526064016105bc565b61105f84610f60565b801561107b575060008481526008602052604090206003015415155b6110c05760405162461bcd60e51b81526020600482015260166024820152751d5d1a5b1a5d1e5259081a5cc81b9bdd081d985b1a5960521b60448201526064016105bc565b6007816040516110d09190612e92565b9081526040519081900360200190205460ff16156111305760405162461bcd60e51b815260206004820152601f60248201527f5369676e61747572652068617320616c7265616479206265656e20757365640060448201526064016105bc565b600084815260086020526040902060038101546002909101546111539085611c05565b11156111ac5760405162461bcd60e51b815260206004820152602260248201527f51747920746f6b656e7320776f756c6420657863656564206d617820737570706044820152616c7960f01b60648201526084016105bc565b60008481526008602052604090206004015433906001600160a01b03161561124657333b151580156111f757506000858152600860205260409020600401546001600160a01b031633145b6112435760405162461bcd60e51b815260206004820152601960248201527f53656e646572206973206e6f74206120636f6e74726163742e0000000000000060448201526064016105bc565b50325b6112538186868686610e55565b6112985760405162461bcd60e51b815260206004820152601660248201527514da59db985d1d5c99481a5cc81b9bdd081d985b1a5960521b60448201526064016105bc565b60016007836040516112aa9190612e92565b9081526040805160209281900383019020805460ff1916931515939093179092556000878152600890915220600201546112e49085611c05565b600860008781526020019081526020016000206002018190555061131981868660405180602001604052806000815250611c18565b604080516001600160a01b0383168152602081018790529081018590527f96234cb3d6c373a1aaa06497a540bc166d4b0359243a088eaf95e21d7253d0be9060600160405180910390a15061136e6001600455565b50505050565b61137c611517565b600b5461138a906001611c05565b600b5560008481526008602052604090208481556001016113ab8482612d92565b50600093845260086020526040909320600381019190915560040180546001600160a01b0319166001600160a01b039093169290921790915550565b6001600160a01b03851633148061140357506114038533610501565b61141f5760405162461bcd60e51b81526004016105bc90612ccf565b610aff8585858585611d23565b611434611517565b6001600160a01b0381166114995760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105bc565b610c1981611ad3565b60006001600160e01b03198216636cdb3d1360e11b14806114d357506001600160e01b031982166303a24d0760e21b145b806105e857506301ffc9a760e01b6001600160e01b03198316146105e8565b60006001600160e01b0319821663152a902d60e11b14806105e857506105e8826114a2565b6003546001600160a01b03163314610f5e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105bc565b6127106001600160601b03821611156115df5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084016105bc565b6001600160a01b0382166116355760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c69642072656365697665720000000000000060448201526064016105bc565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600555565b6060600061167b83611e4d565b60010190506000816001600160401b0381111561169a5761169a6125c7565b6040519080825280601f01601f1916602001820160405280156116c4576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846116ce57509392505050565b81518351146117625760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016105bc565b6001600160a01b0384166117885760405162461bcd60e51b81526004016105bc90612eae565b3360005b845181101561186f5760008582815181106117a9576117a9612d1d565b6020026020010151905060008583815181106117c7576117c7612d1d565b602090810291909101810151600084815280835260408082206001600160a01b038e1683529093529190912054909150818110156118175760405162461bcd60e51b81526004016105bc90612ef3565b6000838152602081815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290611854908490612f3d565b925050819055505050508061186890612d33565b905061178c565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516118bf929190612f50565b60405180910390a46118d5818787878787611f25565b505050505050565b60026004540361192f5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016105bc565b6002600455565b6001600160a01b0383166119985760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b60648201526084016105bc565b3360006119a484612080565b905060006119b184612080565b60408051602080820183526000918290528882528181528282206001600160a01b038b1683529052205490915084811015611a3a5760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b60648201526084016105bc565b6000868152602081815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46040805160208101909152600090525b50505050505050565b6000806000611ac685856120cb565b91509150610e398161210d565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b031603611b985760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016105bc565b6001600160a01b03838116600081815260016020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6000611c118284612f3d565b9392505050565b6001600160a01b038416611c785760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b60648201526084016105bc565b336000611c8485612080565b90506000611c9185612080565b90506000868152602081815260408083206001600160a01b038b16845290915281208054879290611cc3908490612f3d565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4611aae83600089898989612257565b6001600160a01b038416611d495760405162461bcd60e51b81526004016105bc90612eae565b336000611d5585612080565b90506000611d6285612080565b90506000868152602081815260408083206001600160a01b038c16845290915290205485811015611da55760405162461bcd60e51b81526004016105bc90612ef3565b6000878152602081815260408083206001600160a01b038d8116855292528083208985039055908a16825281208054889290611de2908490612f3d565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4611e42848a8a8a8a8a612257565b505050505050505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310611e8c5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310611eb8576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310611ed657662386f26fc10000830492506010015b6305f5e1008310611eee576305f5e100830492506008015b6127108310611f0257612710830492506004015b60648310611f14576064830492506002015b600a83106105e85760010192915050565b6001600160a01b0384163b156118d55760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190611f699089908990889088908890600401612f7e565b6020604051808303816000875af1925050508015611fa4575060408051601f3d908101601f19168201909252611fa191810190612fdc565b60015b61205057611fb0612ff9565b806308c379a003611fe95750611fc4613015565b80611fcf5750611feb565b8060405162461bcd60e51b81526004016105bc91906124e2565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016105bc565b6001600160e01b0319811663bc197c8160e01b14611aae5760405162461bcd60e51b81526004016105bc9061309e565b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106120ba576120ba612d1d565b602090810291909101015292915050565b60008082516041036121015760208301516040840151606085015160001a6120f587828585612312565b945094505050506109f1565b506000905060026109f1565b6000816004811115612121576121216130e6565b036121295750565b600181600481111561213d5761213d6130e6565b0361218a5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105bc565b600281600481111561219e5761219e6130e6565b036121eb5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105bc565b60038160048111156121ff576121ff6130e6565b03610c195760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016105bc565b6001600160a01b0384163b156118d55760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e619061229b90899089908890889088906004016130fc565b6020604051808303816000875af19250505080156122d6575060408051601f3d908101601f191682019092526122d391810190612fdc565b60015b6122e257611fb0612ff9565b6001600160e01b0319811663f23a6e6160e01b14611aae5760405162461bcd60e51b81526004016105bc9061309e565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561234957506000905060036123cd565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561239d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166123c6576000600192509250506123cd565b9150600090505b94509492505050565b80356001600160a01b03811681146123ed57600080fd5b919050565b6000806040838503121561240557600080fd5b61240e836123d6565b946020939093013593505050565b6001600160e01b031981168114610c1957600080fd5b60006020828403121561244457600080fd5b8135611c118161241c565b6000806040838503121561246257600080fd5b61246b836123d6565b915060208301356001600160601b038116811461248757600080fd5b809150509250929050565b60005b838110156124ad578181015183820152602001612495565b50506000910152565b600081518084526124ce816020860160208601612492565b601f01601f19169290920160200192915050565b602081526000611c1160208301846124b6565b60006020828403121561250757600080fd5b5035919050565b60208152815160208201526000602083015160a0604084015261253460c08401826124b6565b9050604084015160608401526060840151608084015260018060a01b0360808501511660a08401528091505092915050565b6000806040838503121561257957600080fd5b50508035926020909101359150565b85815260a0602082015260006125a160a08301876124b6565b60408301959095525060608101929092526001600160a01b031660809091015292915050565b634e487b7160e01b600052604160045260246000fd5b601f8201601f191681016001600160401b0381118282101715612602576126026125c7565b6040525050565b60006001600160401b03821115612622576126226125c7565b5060051b60200190565b600082601f83011261263d57600080fd5b8135602061264a82612609565b60405161265782826125dd565b83815260059390931b850182019282810191508684111561267757600080fd5b8286015b84811015612692578035835291830191830161267b565b509695505050505050565b600082601f8301126126ae57600080fd5b81356001600160401b038111156126c7576126c76125c7565b6040516126de601f8301601f1916602001826125dd565b8181528460208386010111156126f357600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561272857600080fd5b612731866123d6565b945061273f602087016123d6565b935060408601356001600160401b038082111561275b57600080fd5b61276789838a0161262c565b9450606088013591508082111561277d57600080fd5b61278989838a0161262c565b9350608088013591508082111561279f57600080fd5b506127ac8882890161269d565b9150509295509295909350565b600080604083850312156127cc57600080fd5b823591506127dc602084016123d6565b90509250929050565b803580151581146123ed57600080fd5b60006020828403121561280757600080fd5b611c11826127e5565b6000806040838503121561282357600080fd5b82356001600160401b038082111561283a57600080fd5b818501915085601f83011261284e57600080fd5b8135602061285b82612609565b60405161286882826125dd565b83815260059390931b850182019282810191508984111561288857600080fd5b948201945b838610156128ad5761289e866123d6565b8252948201949082019061288d565b965050860135925050808211156128c357600080fd5b506128d08582860161262c565b9150509250929050565b600081518084526020808501945080840160005b8381101561290a578151875295820195908201906001016128ee565b509495945050505050565b602081526000611c1160208301846128da565b60006020828403121561293a57600080fd5b81356001600160401b0381111561295057600080fd5b61295c8482850161269d565b949350505050565b600080600080600060a0868803121561297c57600080fd5b612985866123d6565b9450602086013593506040860135925060608601356001600160401b03808211156129af57600080fd5b61278989838a0161269d565b6000602082840312156129cd57600080fd5b611c11826123d6565b600080604083850312156129e957600080fd5b8235915060208301356001600160401b03811115612a0657600080fd5b6128d08582860161269d565b60008060408385031215612a2557600080fd5b612a2e836123d6565b91506127dc602084016127e5565b60008060008060808587031215612a5257600080fd5b843593506020850135925060408501356001600160401b0380821115612a7757600080fd5b612a838883890161269d565b93506060870135915080821115612a9957600080fd5b50612aa68782880161269d565b91505092959194509250565b60008060008060808587031215612ac857600080fd5b8435935060208501356001600160401b03811115612ae557600080fd5b612af18782880161269d565b93505060408501359150612b07606086016123d6565b905092959194509250565b60008060408385031215612b2557600080fd5b612b2e836123d6565b91506127dc602084016123d6565b600080600080600060a08688031215612b5457600080fd5b612b5d866123d6565b9450612b6b602087016123d6565b9350604086013592506060860135915060808601356001600160401b03811115612b9457600080fd5b6127ac8882890161269d565b600181811c90821680612bb457607f821691505b602082108103612bd457634e487b7160e01b600052602260045260246000fd5b50919050565b60008154612be781612ba0565b60018281168015612bff5760018114612c1457612c43565b60ff1984168752821515830287019450612c43565b8560005260208060002060005b85811015612c3a5781548a820152908401908201612c21565b50505082870194505b5050505092915050565b6000612c598286612bda565b8451612c69818360208901612492565b612c7581830186612bda565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176105e8576105e8612c80565b600082612cca57634e487b7160e01b600052601260045260246000fd5b500490565b6020808252602e908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526d195c881bdc88185c1c1c9bdd995960921b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b600060018201612d4557612d45612c80565b5060010190565b601f821115610fa557600081815260208120601f850160051c81016020861015612d735750805b601f850160051c820191505b818110156118d557828155600101612d7f565b81516001600160401b03811115612dab57612dab6125c7565b612dbf81612db98454612ba0565b84612d4c565b602080601f831160018114612df45760008415612ddc5750858301515b600019600386901b1c1916600185901b1785556118d5565b600085815260208120601f198616915b82811015612e2357888601518255948401946001909101908401612e04565b5085821015612e415787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160601b03198560601b16815283601482015282603482015260008251612e82816054850160208701612492565b9190910160540195945050505050565b60008251612ea4818460208701612492565b9190910192915050565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b808201808211156105e8576105e8612c80565b604081526000612f6360408301856128da565b8281036020840152612f7581856128da565b95945050505050565b6001600160a01b0386811682528516602082015260a060408201819052600090612faa908301866128da565b8281036060840152612fbc81866128da565b90508281036080840152612fd081856124b6565b98975050505050505050565b600060208284031215612fee57600080fd5b8151611c118161241c565b600060033d11156130125760046000803e5060005160e01c5b90565b600060443d10156130235790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561305257505050505090565b828501915081518181111561306a5750505050505090565b843d87010160208285010111156130845750505050505090565b613093602082860101876125dd565b509095945050505050565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b03868116825285166020820152604081018490526060810183905260a060808201819052600090612c75908301846124b656fea264697066735822122034bc9d03e17f6657e7ef2d0ddf5dcd6aeee6a9aa70d580947dfebcc40044954c64736f6c63430008110033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000b1c8ebb5acdd1f22777ce18c6d30134fdc48b6e10000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000a466f636b2053746f726500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000446434b5300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f68747470733a2f2f6170702e746865616c69656e626f792e636f6d2f666f636b73746f72652f6d657461646174612f0000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061021b5760003560e01c80635c7c1a8e11610125578063bb10c829116100ad578063dc2140551161007c578063dc214055146104cd578063e6308717146104e0578063e985e9c5146104f3578063f242432a1461052f578063f2fde38b1461054257600080fd5b8063bb10c82914610471578063bb5b65081461049f578063c08485b7146104b2578063c6682862146104c557600080fd5b80638cc58df4116100f45780638cc58df4146104155780638da5cb5b1461042857806395d89b41146104435780639a2bee911461044b578063a22cb4651461045e57600080fd5b80635c7c1a8e146103de5780636c19e783146103f15780636dbad77814610404578063715018a61461040d57600080fd5b8063379607f5116101a857806348a8f3451161017757806348a8f345146103705780634b014e28146103845780634e1273f4146103975780635303f68c146103b757806355f804b3146103cb57600080fd5b8063379607f51461032f57806337da577c146103425780633ccfd60b146103555780634225cc231461035d57600080fd5b80630e89341c116101ef5780630e89341c1461029357806319234769146102a65780632a55205a146102c65780632d4a2146146102f85780632eb2c2d61461031c57600080fd5b8062fdd58e1461022057806301ffc9a71461024657806304634d8d1461026957806306fdde031461027e575b600080fd5b61023361022e3660046123f2565b610555565b6040519081526020015b60405180910390f35b610259610254366004612432565b6105ee565b604051901515815260200161023d565b61027c61027736600461244f565b610608565b005b61028661061e565b60405161023d91906124e2565b6102866102a13660046124f5565b6106ac565b6102b96102b43660046124f5565b6107dd565b60405161023d919061250e565b6102d96102d4366004612566565b61094a565b604080516001600160a01b03909316835260208301919091520161023d565b61030b6103063660046124f5565b6109f8565b60405161023d959493929190612588565b61027c61032a366004612710565b610aba565b61027c61033d3660046124f5565b610b06565b61027c610350366004612566565b610c1c565b61027c610c39565b61027c61036b3660046127b9565b610cb9565b60095461025990600160a01b900460ff1681565b61027c6103923660046127f5565b610cf2565b6103aa6103a5366004612810565b610d18565b60405161023d9190612915565b60095461025990600160a81b900460ff1681565b61027c6103d9366004612928565b610e41565b6102596103ec366004612964565b610e55565b61027c6103ff3660046129bb565b610f22565b610233600b5481565b61027c610f4c565b6102596104233660046124f5565b610f60565b6003546040516001600160a01b03909116815260200161023d565b610286610f75565b61027c6104593660046129d6565b610f82565b61027c61046c366004612a12565b610faa565b61025961047f366004612928565b805160208183018101805160078252928201919093012091525460ff1681565b61027c6104ad3660046124f5565b610fb5565b61027c6104c03660046127f5565b610fc2565b610286610fe8565b61027c6104db366004612a3c565b610ff5565b61027c6104ee366004612ab2565b611374565b610259610501366004612b12565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205460ff1690565b61027c61053d366004612b3c565b6113e7565b61027c6105503660046129bb565b61142c565b60006001600160a01b0383166105c55760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b60648201526084015b60405180910390fd5b506000818152602081815260408083206001600160a01b03861684529091529020545b92915050565b60006105f9826114a2565b806105e857506105e8826114f2565b610610611517565b61061a8282611571565b5050565b600c805461062b90612ba0565b80601f016020809104026020016040519081016040528092919081815260200182805461065790612ba0565b80156106a45780601f10610679576101008083540402835291602001916106a4565b820191906000526020600020905b81548152906001019060200180831161068757829003601f168201915b505050505081565b60606106b782610f60565b6107035760405162461bcd60e51b815260206004820152601f60248201527f5552492072657175657374656420666f7220696e76616c696420746f6b656e0060448201526064016105bc565b6000600a805461071290612ba0565b9050116107a957600a805461072690612ba0565b80601f016020809104026020016040519081016040528092919081815260200182805461075290612ba0565b801561079f5780601f106107745761010080835404028352916020019161079f565b820191906000526020600020905b81548152906001019060200180831161078257829003601f168201915b50505050506105e8565b600a6107b48361166e565b600e6040516020016107c893929190612c4d565b60405160208183030381529060405292915050565b6108186040518060a001604052806000815260200160608152602001600081526020016000815260200160006001600160a01b031681525090565b61082182610f60565b6108625760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a59081d5d1a5b1a5d1e481a5960721b60448201526064016105bc565b600860008381526020019081526020016000206040518060a00160405290816000820154815260200160018201805461089a90612ba0565b80601f01602080910402602001604051908101604052809291908181526020018280546108c690612ba0565b80156109135780601f106108e857610100808354040283529160200191610913565b820191906000526020600020905b8154815290600101906020018083116108f657829003601f168201915b505050918352505060028201546020820152600382015460408201526004909101546001600160a01b031660609091015292915050565b60008281526006602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925282916109bf5750604080518082019091526005546001600160a01b0381168252600160a01b90046001600160601b031660208201525b6020810151600090612710906109de906001600160601b031687612c96565b6109e89190612cad565b91519350909150505b9250929050565b60086020526000908152604090208054600182018054919291610a1a90612ba0565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4690612ba0565b8015610a935780601f10610a6857610100808354040283529160200191610a93565b820191906000526020600020905b815481529060010190602001808311610a7657829003601f168201915b5050505060028301546003840154600490940154929390929091506001600160a01b031685565b6001600160a01b038516331480610ad65750610ad68533610501565b610af25760405162461bcd60e51b81526004016105bc90612ccf565b610aff8585858585611700565b5050505050565b610b0e6118dd565b600954600160a81b900460ff16610b675760405162461bcd60e51b815260206004820152601d60248201527f436c61696d206973206e6f7420616374697665207269676874206e6f7700000060448201526064016105bc565b6000610b733383610555565b11610bca5760405162461bcd60e51b815260206004820152602160248201527f42616c616e6365206d7573742062652067726561746572207468616e205a65726044820152606f60f81b60648201526084016105bc565b610bd633826001611936565b60408051338152602081018390527fe42df0d9493dfd0d7f69902c895b94c190a53e8c27876a86f45e7c997d9d8f7c910160405180910390a1610c196001600455565b50565b610c24611517565b60009182526008602052604090912060030155565b610c41611517565b60004711610c8a5760405162461bcd60e51b81526020600482015260166024820152754e6f2062616c616e636520746f20776974686472617760501b60448201526064016105bc565b6040514790339082156108fc029083906000818181858888f1935050505015801561061a573d6000803e3d6000fd5b610cc1611517565b60009182526008602052604090912060040180546001600160a01b0319166001600160a01b03909216919091179055565b610cfa611517565b60098054911515600160a81b0260ff60a81b19909216919091179055565b60608151835114610d7d5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016105bc565b600083516001600160401b03811115610d9857610d986125c7565b604051908082528060200260200182016040528015610dc1578160200160208202803683370190505b50905060005b8451811015610e3957610e0c858281518110610de557610de5612d1d565b6020026020010151858381518110610dff57610dff612d1d565b6020026020010151610555565b828281518110610e1e57610e1e612d1d565b6020908102919091010152610e3281612d33565b9050610dc7565b509392505050565b610e49611517565b600a61061a8282612d92565b60008086868686604051602001610e6f9493929190612e51565b6040516020818303038152906040528051906020012090506000610ee0826040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000610eee8286611ab7565b90506001600160a01b03811615801590610f1557506009546001600160a01b038281169116145b9998505050505050505050565b610f2a611517565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b610f54611517565b610f5e6000611ad3565b565b600080821180156105e8575050600b54101590565b600d805461062b90612ba0565b610f8a611517565b6000828152600860205260409020600101610fa58282612d92565b505050565b61061a338383611b25565b610fbd611517565b600b55565b610fca611517565b60098054911515600160a01b0260ff60a01b19909216919091179055565b600e805461062b90612ba0565b610ffd6118dd565b600954600160a01b900460ff166110565760405162461bcd60e51b815260206004820152601f60248201527f4d696e74206973206e6f7420617661696c61626c65207269676874206e6f770060448201526064016105bc565b61105f84610f60565b801561107b575060008481526008602052604090206003015415155b6110c05760405162461bcd60e51b81526020600482015260166024820152751d5d1a5b1a5d1e5259081a5cc81b9bdd081d985b1a5960521b60448201526064016105bc565b6007816040516110d09190612e92565b9081526040519081900360200190205460ff16156111305760405162461bcd60e51b815260206004820152601f60248201527f5369676e61747572652068617320616c7265616479206265656e20757365640060448201526064016105bc565b600084815260086020526040902060038101546002909101546111539085611c05565b11156111ac5760405162461bcd60e51b815260206004820152602260248201527f51747920746f6b656e7320776f756c6420657863656564206d617820737570706044820152616c7960f01b60648201526084016105bc565b60008481526008602052604090206004015433906001600160a01b03161561124657333b151580156111f757506000858152600860205260409020600401546001600160a01b031633145b6112435760405162461bcd60e51b815260206004820152601960248201527f53656e646572206973206e6f74206120636f6e74726163742e0000000000000060448201526064016105bc565b50325b6112538186868686610e55565b6112985760405162461bcd60e51b815260206004820152601660248201527514da59db985d1d5c99481a5cc81b9bdd081d985b1a5960521b60448201526064016105bc565b60016007836040516112aa9190612e92565b9081526040805160209281900383019020805460ff1916931515939093179092556000878152600890915220600201546112e49085611c05565b600860008781526020019081526020016000206002018190555061131981868660405180602001604052806000815250611c18565b604080516001600160a01b0383168152602081018790529081018590527f96234cb3d6c373a1aaa06497a540bc166d4b0359243a088eaf95e21d7253d0be9060600160405180910390a15061136e6001600455565b50505050565b61137c611517565b600b5461138a906001611c05565b600b5560008481526008602052604090208481556001016113ab8482612d92565b50600093845260086020526040909320600381019190915560040180546001600160a01b0319166001600160a01b039093169290921790915550565b6001600160a01b03851633148061140357506114038533610501565b61141f5760405162461bcd60e51b81526004016105bc90612ccf565b610aff8585858585611d23565b611434611517565b6001600160a01b0381166114995760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105bc565b610c1981611ad3565b60006001600160e01b03198216636cdb3d1360e11b14806114d357506001600160e01b031982166303a24d0760e21b145b806105e857506301ffc9a760e01b6001600160e01b03198316146105e8565b60006001600160e01b0319821663152a902d60e11b14806105e857506105e8826114a2565b6003546001600160a01b03163314610f5e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105bc565b6127106001600160601b03821611156115df5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084016105bc565b6001600160a01b0382166116355760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c69642072656365697665720000000000000060448201526064016105bc565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600555565b6060600061167b83611e4d565b60010190506000816001600160401b0381111561169a5761169a6125c7565b6040519080825280601f01601f1916602001820160405280156116c4576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846116ce57509392505050565b81518351146117625760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016105bc565b6001600160a01b0384166117885760405162461bcd60e51b81526004016105bc90612eae565b3360005b845181101561186f5760008582815181106117a9576117a9612d1d565b6020026020010151905060008583815181106117c7576117c7612d1d565b602090810291909101810151600084815280835260408082206001600160a01b038e1683529093529190912054909150818110156118175760405162461bcd60e51b81526004016105bc90612ef3565b6000838152602081815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290611854908490612f3d565b925050819055505050508061186890612d33565b905061178c565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516118bf929190612f50565b60405180910390a46118d5818787878787611f25565b505050505050565b60026004540361192f5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016105bc565b6002600455565b6001600160a01b0383166119985760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b60648201526084016105bc565b3360006119a484612080565b905060006119b184612080565b60408051602080820183526000918290528882528181528282206001600160a01b038b1683529052205490915084811015611a3a5760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b60648201526084016105bc565b6000868152602081815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46040805160208101909152600090525b50505050505050565b6000806000611ac685856120cb565b91509150610e398161210d565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b031603611b985760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016105bc565b6001600160a01b03838116600081815260016020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6000611c118284612f3d565b9392505050565b6001600160a01b038416611c785760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b60648201526084016105bc565b336000611c8485612080565b90506000611c9185612080565b90506000868152602081815260408083206001600160a01b038b16845290915281208054879290611cc3908490612f3d565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4611aae83600089898989612257565b6001600160a01b038416611d495760405162461bcd60e51b81526004016105bc90612eae565b336000611d5585612080565b90506000611d6285612080565b90506000868152602081815260408083206001600160a01b038c16845290915290205485811015611da55760405162461bcd60e51b81526004016105bc90612ef3565b6000878152602081815260408083206001600160a01b038d8116855292528083208985039055908a16825281208054889290611de2908490612f3d565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4611e42848a8a8a8a8a612257565b505050505050505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310611e8c5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310611eb8576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310611ed657662386f26fc10000830492506010015b6305f5e1008310611eee576305f5e100830492506008015b6127108310611f0257612710830492506004015b60648310611f14576064830492506002015b600a83106105e85760010192915050565b6001600160a01b0384163b156118d55760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190611f699089908990889088908890600401612f7e565b6020604051808303816000875af1925050508015611fa4575060408051601f3d908101601f19168201909252611fa191810190612fdc565b60015b61205057611fb0612ff9565b806308c379a003611fe95750611fc4613015565b80611fcf5750611feb565b8060405162461bcd60e51b81526004016105bc91906124e2565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016105bc565b6001600160e01b0319811663bc197c8160e01b14611aae5760405162461bcd60e51b81526004016105bc9061309e565b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106120ba576120ba612d1d565b602090810291909101015292915050565b60008082516041036121015760208301516040840151606085015160001a6120f587828585612312565b945094505050506109f1565b506000905060026109f1565b6000816004811115612121576121216130e6565b036121295750565b600181600481111561213d5761213d6130e6565b0361218a5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105bc565b600281600481111561219e5761219e6130e6565b036121eb5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105bc565b60038160048111156121ff576121ff6130e6565b03610c195760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016105bc565b6001600160a01b0384163b156118d55760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e619061229b90899089908890889088906004016130fc565b6020604051808303816000875af19250505080156122d6575060408051601f3d908101601f191682019092526122d391810190612fdc565b60015b6122e257611fb0612ff9565b6001600160e01b0319811663f23a6e6160e01b14611aae5760405162461bcd60e51b81526004016105bc9061309e565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561234957506000905060036123cd565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561239d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166123c6576000600192509250506123cd565b9150600090505b94509492505050565b80356001600160a01b03811681146123ed57600080fd5b919050565b6000806040838503121561240557600080fd5b61240e836123d6565b946020939093013593505050565b6001600160e01b031981168114610c1957600080fd5b60006020828403121561244457600080fd5b8135611c118161241c565b6000806040838503121561246257600080fd5b61246b836123d6565b915060208301356001600160601b038116811461248757600080fd5b809150509250929050565b60005b838110156124ad578181015183820152602001612495565b50506000910152565b600081518084526124ce816020860160208601612492565b601f01601f19169290920160200192915050565b602081526000611c1160208301846124b6565b60006020828403121561250757600080fd5b5035919050565b60208152815160208201526000602083015160a0604084015261253460c08401826124b6565b9050604084015160608401526060840151608084015260018060a01b0360808501511660a08401528091505092915050565b6000806040838503121561257957600080fd5b50508035926020909101359150565b85815260a0602082015260006125a160a08301876124b6565b60408301959095525060608101929092526001600160a01b031660809091015292915050565b634e487b7160e01b600052604160045260246000fd5b601f8201601f191681016001600160401b0381118282101715612602576126026125c7565b6040525050565b60006001600160401b03821115612622576126226125c7565b5060051b60200190565b600082601f83011261263d57600080fd5b8135602061264a82612609565b60405161265782826125dd565b83815260059390931b850182019282810191508684111561267757600080fd5b8286015b84811015612692578035835291830191830161267b565b509695505050505050565b600082601f8301126126ae57600080fd5b81356001600160401b038111156126c7576126c76125c7565b6040516126de601f8301601f1916602001826125dd565b8181528460208386010111156126f357600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561272857600080fd5b612731866123d6565b945061273f602087016123d6565b935060408601356001600160401b038082111561275b57600080fd5b61276789838a0161262c565b9450606088013591508082111561277d57600080fd5b61278989838a0161262c565b9350608088013591508082111561279f57600080fd5b506127ac8882890161269d565b9150509295509295909350565b600080604083850312156127cc57600080fd5b823591506127dc602084016123d6565b90509250929050565b803580151581146123ed57600080fd5b60006020828403121561280757600080fd5b611c11826127e5565b6000806040838503121561282357600080fd5b82356001600160401b038082111561283a57600080fd5b818501915085601f83011261284e57600080fd5b8135602061285b82612609565b60405161286882826125dd565b83815260059390931b850182019282810191508984111561288857600080fd5b948201945b838610156128ad5761289e866123d6565b8252948201949082019061288d565b965050860135925050808211156128c357600080fd5b506128d08582860161262c565b9150509250929050565b600081518084526020808501945080840160005b8381101561290a578151875295820195908201906001016128ee565b509495945050505050565b602081526000611c1160208301846128da565b60006020828403121561293a57600080fd5b81356001600160401b0381111561295057600080fd5b61295c8482850161269d565b949350505050565b600080600080600060a0868803121561297c57600080fd5b612985866123d6565b9450602086013593506040860135925060608601356001600160401b03808211156129af57600080fd5b61278989838a0161269d565b6000602082840312156129cd57600080fd5b611c11826123d6565b600080604083850312156129e957600080fd5b8235915060208301356001600160401b03811115612a0657600080fd5b6128d08582860161269d565b60008060408385031215612a2557600080fd5b612a2e836123d6565b91506127dc602084016127e5565b60008060008060808587031215612a5257600080fd5b843593506020850135925060408501356001600160401b0380821115612a7757600080fd5b612a838883890161269d565b93506060870135915080821115612a9957600080fd5b50612aa68782880161269d565b91505092959194509250565b60008060008060808587031215612ac857600080fd5b8435935060208501356001600160401b03811115612ae557600080fd5b612af18782880161269d565b93505060408501359150612b07606086016123d6565b905092959194509250565b60008060408385031215612b2557600080fd5b612b2e836123d6565b91506127dc602084016123d6565b600080600080600060a08688031215612b5457600080fd5b612b5d866123d6565b9450612b6b602087016123d6565b9350604086013592506060860135915060808601356001600160401b03811115612b9457600080fd5b6127ac8882890161269d565b600181811c90821680612bb457607f821691505b602082108103612bd457634e487b7160e01b600052602260045260246000fd5b50919050565b60008154612be781612ba0565b60018281168015612bff5760018114612c1457612c43565b60ff1984168752821515830287019450612c43565b8560005260208060002060005b85811015612c3a5781548a820152908401908201612c21565b50505082870194505b5050505092915050565b6000612c598286612bda565b8451612c69818360208901612492565b612c7581830186612bda565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176105e8576105e8612c80565b600082612cca57634e487b7160e01b600052601260045260246000fd5b500490565b6020808252602e908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526d195c881bdc88185c1c1c9bdd995960921b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b600060018201612d4557612d45612c80565b5060010190565b601f821115610fa557600081815260208120601f850160051c81016020861015612d735750805b601f850160051c820191505b818110156118d557828155600101612d7f565b81516001600160401b03811115612dab57612dab6125c7565b612dbf81612db98454612ba0565b84612d4c565b602080601f831160018114612df45760008415612ddc5750858301515b600019600386901b1c1916600185901b1785556118d5565b600085815260208120601f198616915b82811015612e2357888601518255948401946001909101908401612e04565b5085821015612e415787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160601b03198560601b16815283601482015282603482015260008251612e82816054850160208701612492565b9190910160540195945050505050565b60008251612ea4818460208701612492565b9190910192915050565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b808201808211156105e8576105e8612c80565b604081526000612f6360408301856128da565b8281036020840152612f7581856128da565b95945050505050565b6001600160a01b0386811682528516602082015260a060408201819052600090612faa908301866128da565b8281036060840152612fbc81866128da565b90508281036080840152612fd081856124b6565b98975050505050505050565b600060208284031215612fee57600080fd5b8151611c118161241c565b600060033d11156130125760046000803e5060005160e01c5b90565b600060443d10156130235790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561305257505050505090565b828501915081518181111561306a5750505050505090565b843d87010160208285010111156130845750505050505090565b613093602082860101876125dd565b509095945050505050565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b03868116825285166020820152604081018490526060810183905260a060808201819052600090612c75908301846124b656fea264697066735822122034bc9d03e17f6657e7ef2d0ddf5dcd6aeee6a9aa70d580947dfebcc40044954c64736f6c63430008110033

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

000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000b1c8ebb5acdd1f22777ce18c6d30134fdc48b6e10000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000a466f636b2053746f726500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000446434b5300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f68747470733a2f2f6170702e746865616c69656e626f792e636f6d2f666f636b73746f72652f6d657461646174612f0000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _name (string): Fock Store
Arg [1] : _symbol (string): FCKS
Arg [2] : _signer (address): 0xB1c8Ebb5aCDD1f22777CE18c6d30134fdC48b6E1
Arg [3] : _baseURI (string): https://app.thealienboy.com/fockstore/metadata/

-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 000000000000000000000000b1c8ebb5acdd1f22777ce18c6d30134fdc48b6e1
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [4] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [5] : 466f636b2053746f726500000000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [7] : 46434b5300000000000000000000000000000000000000000000000000000000
Arg [8] : 000000000000000000000000000000000000000000000000000000000000002f
Arg [9] : 68747470733a2f2f6170702e746865616c69656e626f792e636f6d2f666f636b
Arg [10] : 73746f72652f6d657461646174612f0000000000000000000000000000000000


Deployed Bytecode Sourcemap

12164:7145:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2130:227:3;;;;;;:::i;:::-;;:::i;:::-;;;597:25:17;;;585:2;570:18;2130:227:3;;;;;;;;16667:258:6;;;;;;:::i;:::-;;:::i;:::-;;;1184:14:17;;1177:22;1159:41;;1147:2;1132:18;16667:258:6;1019:187:17;16477:142:6;;;;;;:::i;:::-;;:::i;:::-;;13033:18;;;:::i;:::-;;;;;;;:::i;15850:340::-;;;;;;:::i;:::-;;:::i;15397:190::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1632:432:5:-;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;3608:32:17;;;3590:51;;3672:2;3657:18;;3650:34;;;;3563:18;1632:432:5;3416:274:17;12692:44:6;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;4009:426:3:-;;;;;;:::i;:::-;;:::i;18985:322:6:-;;;;;;:::i;:::-;;:::i;14642:128::-;;;;;;:::i;:::-;;:::i;16228:208::-;;;:::i;14835:164::-;;;;;;:::i;:::-;;:::i;12838:33::-;;;;;-1:-1:-1;;;12838:33:6;;;;;;14033:98;;;;;;:::i;:::-;;:::i;2514:508:3:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;12911:32:6:-;;;;;-1:-1:-1;;;12911:32:6;;;;;;15707:96;;;;;;:::i;:::-;;:::i;17156:510::-;;;;;;:::i;:::-;;:::i;13700:86::-;;;;;;:::i;:::-;;:::i;12995:31::-;;;;;;1824:101:13;;;:::i;16973:140:6:-;;;;;;:::i;:::-;;:::i;1194:85:13:-;1266:6;;1194:85;;-1:-1:-1;;;;;1266:6:13;;;10992:51:17;;10980:2;10965:18;1194:85:13;10846:203:17;13057:20:6;;;:::i;15049:133::-;;;;;;:::i;:::-;;:::i;3090:153:3:-;;;;;;:::i;:::-;;:::i;12642:43:6:-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15239:110;;;;;;:::i;:::-;;:::i;13860:100::-;;;;;;:::i;:::-;;:::i;13083:37::-;;;:::i;17710:1234::-;;;;;;:::i;:::-;;:::i;14190:393::-;;;;;;:::i;:::-;;:::i;3310:166:3:-;;;;;;:::i;:::-;-1:-1:-1;;;;;3432:27:3;;;3409:4;3432:27;;;:18;:27;;;;;;;;:37;;;;;;;;;;;;;;;3310:166;3543:394;;;;;;:::i;:::-;;:::i;2074:198:13:-;;;;;;:::i;:::-;;:::i;2130:227:3:-;2216:7;-1:-1:-1;;;;;2243:21:3;;2235:76;;;;-1:-1:-1;;;2235:76:3;;14329:2:17;2235:76:3;;;14311:21:17;14368:2;14348:18;;;14341:30;14407:34;14387:18;;;14380:62;-1:-1:-1;;;14458:18:17;;;14451:40;14508:19;;2235:76:3;;;;;;;;;-1:-1:-1;2328:9:3;:13;;;;;;;;;;;-1:-1:-1;;;;;2328:22:3;;;;;;;;;;2130:227;;;;;:::o;16667:258:6:-;16811:4;16838:38;16864:11;16838:25;:38::i;:::-;:80;;;;16880:38;16906:11;16880:25;:38::i;16477:142::-;1087:13:13;:11;:13::i;:::-;16570:42:6::1;16589:8;16599:12;16570:18;:42::i;:::-;16477:142:::0;;:::o;13033:18::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;15850:340::-;15913:13;15950:26;15965:10;15950:14;:26::i;:::-;15942:70;;;;-1:-1:-1;;;15942:70:6;;15125:2:17;15942:70:6;;;15107:21:17;15164:2;15144:18;;;15137:30;15203:33;15183:18;;;15176:61;15254:18;;15942:70:6;14923:355:17;15942:70:6;16066:1;16048:7;16042:21;;;;;:::i;:::-;;;:25;:141;;16176:7;16042:141;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16110:7;16119:21;:10;:19;:21::i;:::-;16142:13;16093:63;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;16023:160;15850:340;-1:-1:-1;;15850:340:6:o;15397:190::-;15458:14;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15458:14:6;15492:26;15507:10;15492:14;:26::i;:::-;15484:57;;;;-1:-1:-1;;;15484:57:6;;16812:2:17;15484:57:6;;;16794:21:17;16851:2;16831:18;;;16824:30;-1:-1:-1;;;16870:18:17;;;16863:48;16928:18;;15484:57:6;16610:342:17;15484:57:6;15559:9;:21;15569:10;15559:21;;;;;;;;;;;15552:28;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;15552:28:6;;;-1:-1:-1;;15552:28:6;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;15552:28:6;;;;;;;15397:190;-1:-1:-1;;15397:190:6:o;1632:432:5:-;1729:7;1786:27;;;:17;:27;;;;;;;;1757:56;;;;;;;;;-1:-1:-1;;;;;1757:56:5;;;;;-1:-1:-1;;;1757:56:5;;;-1:-1:-1;;;;;1757:56:5;;;;;;;;1729:7;;1824:90;;-1:-1:-1;1874:29:5;;;;;;;;;1884:19;1874:29;-1:-1:-1;;;;;1874:29:5;;;;-1:-1:-1;;;1874:29:5;;-1:-1:-1;;;;;1874:29:5;;;;;1824:90;1962:23;;;;1924:21;;2422:5;;1949:36;;-1:-1:-1;;;;;1949:36:5;:10;:36;:::i;:::-;1948:58;;;;:::i;:::-;2025:16;;;-1:-1:-1;1924:82:5;;-1:-1:-1;;1632:432:5;;;;;;:::o;12692:44:6:-;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;12692:44:6;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;12692:44:6;;:::o;4009:426:3:-;-1:-1:-1;;;;;4234:20:3;;719:10:1;4234:20:3;;:60;;-1:-1:-1;4258:36:3;4275:4;719:10:1;3310:166:3;:::i;4258:36::-;4213:153;;;;-1:-1:-1;;;4213:153:3;;;;;;;:::i;:::-;4376:52;4399:4;4405:2;4409:3;4414:7;4423:4;4376:22;:52::i;:::-;4009:426;;;;;:::o;18985:322:6:-;2261:21:14;:19;:21::i;:::-;19057:13:6::1;::::0;-1:-1:-1;;;19057:13:6;::::1;;;19049:55;;;::::0;-1:-1:-1;;;19049:55:6;;18233:2:17;19049:55:6::1;::::0;::::1;18215:21:17::0;18272:2;18252:18;;;18245:30;18311:31;18291:18;;;18284:59;18360:18;;19049:55:6::1;18031:353:17::0;19049:55:6::1;19158:1;19122:33;19132:10;19144;19122:9;:33::i;:::-;:37;19114:83;;;::::0;-1:-1:-1;;;19114:83:6;;18591:2:17;19114:83:6::1;::::0;::::1;18573:21:17::0;18630:2;18610:18;;;18603:30;18669:34;18649:18;;;18642:62;-1:-1:-1;;;18720:18:17;;;18713:31;18761:19;;19114:83:6::1;18389:397:17::0;19114:83:6::1;19216:38;19228:10;19240;19252:1;19216:11;:38::i;:::-;19264:36;::::0;;19277:10:::1;3590:51:17::0;;3672:2;3657:18;;3650:34;;;19264:36:6::1;::::0;3563:18:17;19264:36:6::1;;;;;;;2303:20:14::0;1716:1;2809:7;:22;2629:209;2303:20;18985:322:6;:::o;14642:128::-;1087:13:13;:11;:13::i;:::-;14725:21:6::1;::::0;;;:9:::1;:21;::::0;;;;;:31:::1;;:38:::0;14642:128::o;16228:208::-;1087:13:13;:11;:13::i;:::-;16307:1:6::1;16283:21;:25;16275:60;;;::::0;-1:-1:-1;;;16275:60:6;;18993:2:17;16275:60:6::1;::::0;::::1;18975:21:17::0;19032:2;19012:18;;;19005:30;-1:-1:-1;;;19051:18:17;;;19044:52;19113:18;;16275:60:6::1;18791:346:17::0;16275:60:6::1;16392:37;::::0;16361:21:::1;::::0;16400:10:::1;::::0;16392:37;::::1;;;::::0;16361:21;;16346:12:::1;16392:37:::0;16346:12;16392:37;16361:21;16400:10;16392:37;::::1;;;;;;;;;;;;;::::0;::::1;;;;14835:164:::0;1087:13:13;:11;:13::i;:::-;14936:21:6::1;::::0;;;:9:::1;:21;::::0;;;;;:37:::1;;:56:::0;;-1:-1:-1;;;;;;14936:56:6::1;-1:-1:-1::0;;;;;14936:56:6;;::::1;::::0;;;::::1;::::0;;14835:164::o;14033:98::-;1087:13:13;:11;:13::i;:::-;14099::6::1;:25:::0;;;::::1;;-1:-1:-1::0;;;14099:25:6::1;-1:-1:-1::0;;;;14099:25:6;;::::1;::::0;;;::::1;::::0;;14033:98::o;2514:508:3:-;2665:16;2724:3;:10;2705:8;:15;:29;2697:83;;;;-1:-1:-1;;;2697:83:3;;19344:2:17;2697:83:3;;;19326:21:17;19383:2;19363:18;;;19356:30;19422:34;19402:18;;;19395:62;-1:-1:-1;;;19473:18:17;;;19466:39;19522:19;;2697:83:3;19142:405:17;2697:83:3;2791:30;2838:8;:15;-1:-1:-1;;;;;2824:30:3;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2824:30:3;;2791:63;;2870:9;2865:120;2889:8;:15;2885:1;:19;2865:120;;;2944:30;2954:8;2963:1;2954:11;;;;;;;;:::i;:::-;;;;;;;2967:3;2971:1;2967:6;;;;;;;;:::i;:::-;;;;;;;2944:9;:30::i;:::-;2925:13;2939:1;2925:16;;;;;;;;:::i;:::-;;;;;;;;;;:49;2906:3;;;:::i;:::-;;;2865:120;;;-1:-1:-1;3002:13:3;2514:508;-1:-1:-1;;;2514:508:3:o;15707:96:6:-;1087:13:13;:11;:13::i;:::-;15778:7:6::1;:18;15788:8:::0;15778:7;:18:::1;:::i;17156:510::-:0;17358:4;17374:12;17416:7;17425:10;17437:4;17443:6;17399:51;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;17389:62;;;;;;17374:77;;17461:15;17479:34;17508:4;7454:58:2;;30291:66:17;7454:58:2;;;30279:79:17;30374:12;;;30367:28;;;7324:7:2;;30411:12:17;;7454:58:2;;;;;;;;;;;;7444:69;;;;;;7437:76;;7255:265;;;;17479:34:6;17461:52;;17523:23;17549:34;17563:7;17572:10;17549:13;:34::i;:::-;17523:60;-1:-1:-1;;;;;;17601:29:6;;;;;;:58;;-1:-1:-1;17653:6:6;;-1:-1:-1;;;;;17634:25:6;;;17653:6;;17634:25;17601:58;17594:65;17156:510;-1:-1:-1;;;;;;;;;17156:510:6:o;13700:86::-;1087:13:13;:11;:13::i;:::-;13763:6:6::1;:16:::0;;-1:-1:-1;;;;;;13763:16:6::1;-1:-1:-1::0;;;;;13763:16:6;;;::::1;::::0;;;::::1;::::0;;13700:86::o;1824:101:13:-;1087:13;:11;:13::i;:::-;1888:30:::1;1915:1;1888:18;:30::i;:::-;1824:101::o:0;16973:140:6:-;17037:4;17074:1;17061:10;:14;:44;;;;-1:-1:-1;;17093:12:6;;-1:-1:-1;17079:26:6;;16973:140::o;13057:20::-;;;;;;;:::i;15049:133::-;1087:13:13;:11;:13::i;:::-;15141:21:6::1;::::0;;;:9:::1;:21;::::0;;;;:26:::1;;:34;15170:5:::0;15141:26;:34:::1;:::i;:::-;;15049:133:::0;;:::o;3090:153:3:-;3184:52;719:10:1;3217:8:3;3227;3184:18;:52::i;15239:110:6:-;1087:13:13;:11;:13::i;:::-;15314:12:6::1;:28:::0;15239:110::o;13860:100::-;1087:13:13;:11;:13::i;:::-;13927:14:6::1;:26:::0;;;::::1;;-1:-1:-1::0;;;13927:26:6::1;-1:-1:-1::0;;;;13927:26:6;;::::1;::::0;;;::::1;::::0;;13860:100::o;13083:37::-;;;;;;;:::i;17710:1234::-;2261:21:14;:19;:21::i;:::-;17839:14:6::1;::::0;-1:-1:-1;;;17839:14:6;::::1;;;17831:58;;;::::0;-1:-1:-1;;;17831:58:6;;22649:2:17;17831:58:6::1;::::0;::::1;22631:21:17::0;22688:2;22668:18;;;22661:30;22727:33;22707:18;;;22700:61;22778:18;;17831:58:6::1;22447:355:17::0;17831:58:6::1;17907:26;17922:10;17907:14;:26::i;:::-;:65;;;;-1:-1:-1::0;17971:1:6::1;17937:21:::0;;;:9:::1;:21;::::0;;;;:31:::1;;::::0;:35;;17907:65:::1;17899:100;;;::::0;-1:-1:-1;;;17899:100:6;;23009:2:17;17899:100:6::1;::::0;::::1;22991:21:17::0;23048:2;23028:18;;;23021:30;-1:-1:-1;;;23067:18:17;;;23060:52;23129:18;;17899:100:6::1;22807:346:17::0;17899:100:6::1;18018:13;18032:10;18018:25;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;;::::1;;18017:26;18009:70;;;::::0;-1:-1:-1;;;18009:70:6;;23652:2:17;18009:70:6::1;::::0;::::1;23634:21:17::0;23691:2;23671:18;;;23664:30;23730:33;23710:18;;;23703:61;23781:18;;18009:70:6::1;23450:355:17::0;18009:70:6::1;18144:21;::::0;;;:9:::1;:21;::::0;;;;:31:::1;::::0;::::1;::::0;18097:33:::1;::::0;;::::1;::::0;:43:::1;::::0;18135:4;18097:37:::1;:43::i;:::-;:78;;18089:125;;;::::0;-1:-1:-1;;;18089:125:6;;24012:2:17;18089:125:6::1;::::0;::::1;23994:21:17::0;24051:2;24031:18;;;24024:30;24090:34;24070:18;;;24063:62;-1:-1:-1;;;24141:18:17;;;24134:32;24183:19;;18089:125:6::1;23810:398:17::0;18089:125:6::1;18225:19;18314:21:::0;;;:9:::1;:21;::::0;;;;:37:::1;;::::0;18247:10:::1;::::0;-1:-1:-1;;;;;18314:37:6::1;:51:::0;18310:280:::1;;18400:10;13284:18:::0;13316:8;;18389:77:::1;;;;-1:-1:-1::0;18415:21:6::1;::::0;;;:9:::1;:21;::::0;;;;:37:::1;;::::0;-1:-1:-1;;;;;18415:37:6::1;18456:10;18415:51;18389:77;18381:115;;;::::0;-1:-1:-1;;;18381:115:6;;24415:2:17;18381:115:6::1;::::0;::::1;24397:21:17::0;24454:2;24434:18;;;24427:30;24493:27;24473:18;;;24466:55;24538:18;;18381:115:6::1;24213:349:17::0;18381:115:6::1;-1:-1:-1::0;18570:9:6::1;18310:280;18608:62;18620:11;18633:10;18645:4;18651:6;18659:10;18608:11;:62::i;:::-;18600:97;;;::::0;-1:-1:-1;;;18600:97:6;;24769:2:17;18600:97:6::1;::::0;::::1;24751:21:17::0;24808:2;24788:18;;;24781:30;-1:-1:-1;;;24827:18:17;;;24820:52;24889:18;;18600:97:6::1;24567:346:17::0;18600:97:6::1;18736:4;18708:13;18722:10;18708:25;;;;;;:::i;:::-;::::0;;;::::1;::::0;;::::1;::::0;;;;;;;;:32;;-1:-1:-1;;18708:32:6::1;::::0;::::1;;::::0;;;::::1;::::0;;;-1:-1:-1;18786:21:6;;;:9:::1;:21:::0;;;;:33:::1;;::::0;:43:::1;::::0;18824:4;18786:37:::1;:43::i;:::-;18750:9;:21;18760:10;18750:21;;;;;;;;;;;:33;;:79;;;;18839:40;18845:11;18858:10;18870:4;18839:40;;;;;;;;;;;::::0;:5:::1;:40::i;:::-;18895:42;::::0;;-1:-1:-1;;;;;25138:32:17;;25120:51;;25202:2;25187:18;;25180:34;;;25230:18;;;25223:34;;;18895:42:6::1;::::0;25108:2:17;25093:18;18895:42:6::1;;;;;;;17821:1123;2303:20:14::0;1716:1;2809:7;:22;2629:209;2303:20;17710:1234:6;;;;:::o;14190:393::-;1087:13:13;:11;:13::i;:::-;14339:12:6::1;::::0;:19:::1;::::0;14356:1:::1;14339:16;:19::i;:::-;14324:12;:34:::0;14368:21:::1;::::0;;;:9:::1;:21;::::0;;;;:44;;;14422:26:::1;;:34;14451:5:::0;14422:26;:34:::1;:::i;:::-;-1:-1:-1::0;14466:21:6::1;::::0;;;:9:::1;:21;::::0;;;;;:31:::1;::::0;::::1;:44:::0;;;;14520:37:::1;;:56:::0;;-1:-1:-1;;;;;;14520:56:6::1;-1:-1:-1::0;;;;;14520:56:6;;::::1;::::0;;;::::1;::::0;;;-1:-1:-1;14190:393:6:o;3543:394:3:-;-1:-1:-1;;;;;3743:20:3;;719:10:1;3743:20:3;;:60;;-1:-1:-1;3767:36:3;3784:4;719:10:1;3310:166:3;:::i;3767:36::-;3722:153;;;;-1:-1:-1;;;3722:153:3;;;;;;;:::i;:::-;3885:45;3903:4;3909:2;3913;3917:6;3925:4;3885:17;:45::i;2074:198:13:-;1087:13;:11;:13::i;:::-;-1:-1:-1;;;;;2162:22:13;::::1;2154:73;;;::::0;-1:-1:-1;;;2154:73:13;;25470:2:17;2154:73:13::1;::::0;::::1;25452:21:17::0;25509:2;25489:18;;;25482:30;25548:34;25528:18;;;25521:62;-1:-1:-1;;;25599:18:17;;;25592:36;25645:19;;2154:73:13::1;25268:402:17::0;2154:73:13::1;2237:28;2256:8;2237:18;:28::i;1181:305:3:-:0;1283:4;-1:-1:-1;;;;;;1318:41:3;;-1:-1:-1;;;1318:41:3;;:109;;-1:-1:-1;;;;;;;1375:52:3;;-1:-1:-1;;;1375:52:3;1318:109;:161;;;-1:-1:-1;;;;;;;;;;937:40:4;;;1443:36:3;829:155:4;1369:213:5;1471:4;-1:-1:-1;;;;;;1494:41:5;;-1:-1:-1;;;1494:41:5;;:81;;;1539:36;1563:11;1539:23;:36::i;1352:130:13:-;1266:6;;-1:-1:-1;;;;;1266:6:13;719:10:1;1415:23:13;1407:68;;;;-1:-1:-1;;;1407:68:13;;25877:2:17;1407:68:13;;;25859:21:17;;;25896:18;;;25889:30;25955:34;25935:18;;;25928:62;26007:18;;1407:68:13;25675:356:17;2695:327:5;2422:5;-1:-1:-1;;;;;2797:33:5;;;;2789:88;;;;-1:-1:-1;;;2789:88:5;;26238:2:17;2789:88:5;;;26220:21:17;26277:2;26257:18;;;26250:30;26316:34;26296:18;;;26289:62;-1:-1:-1;;;26367:18:17;;;26360:40;26417:19;;2789:88:5;26036:406:17;2789:88:5;-1:-1:-1;;;;;2895:22:5;;2887:60;;;;-1:-1:-1;;;2887:60:5;;26649:2:17;2887:60:5;;;26631:21:17;26688:2;26668:18;;;26661:30;26727:27;26707:18;;;26700:55;26772:18;;2887:60:5;26447:349:17;2887:60:5;2980:35;;;;;;;;;-1:-1:-1;;;;;2980:35:5;;;;;;-1:-1:-1;;;;;2980:35:5;;;;;;;;;;-1:-1:-1;;;2958:57:5;;;;:19;:57;2695:327::o;410:696:16:-;466:13;515:14;532:17;543:5;532:10;:17::i;:::-;552:1;532:21;515:38;;567:20;601:6;-1:-1:-1;;;;;590:18:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;590:18:16;-1:-1:-1;567:41:16;-1:-1:-1;728:28:16;;;744:2;728:28;783:280;-1:-1:-1;;814:5:16;-1:-1:-1;;;948:2:16;937:14;;932:30;814:5;919:44;1007:2;998:11;;;-1:-1:-1;1027:21:16;783:280;1027:21;-1:-1:-1;1083:6:16;410:696;-1:-1:-1;;;410:696:16:o;6178:1115:3:-;6398:7;:14;6384:3;:10;:28;6376:81;;;;-1:-1:-1;;;6376:81:3;;27003:2:17;6376:81:3;;;26985:21:17;27042:2;27022:18;;;27015:30;27081:34;27061:18;;;27054:62;-1:-1:-1;;;27132:18:17;;;27125:38;27180:19;;6376:81:3;26801:404:17;6376:81:3;-1:-1:-1;;;;;6475:16:3;;6467:66;;;;-1:-1:-1;;;6467:66:3;;;;;;;:::i;:::-;719:10:1;6544:16:3;6657:411;6681:3;:10;6677:1;:14;6657:411;;;6712:10;6725:3;6729:1;6725:6;;;;;;;;:::i;:::-;;;;;;;6712:19;;6745:14;6762:7;6770:1;6762:10;;;;;;;;:::i;:::-;;;;;;;;;;;;6787:19;6809:13;;;;;;;;;;-1:-1:-1;;;;;6809:19:3;;;;;;;;;;;;6762:10;;-1:-1:-1;6850:21:3;;;;6842:76;;;;-1:-1:-1;;;6842:76:3;;;;;;;:::i;:::-;6960:9;:13;;;;;;;;;;;-1:-1:-1;;;;;6960:19:3;;;;;;;;;;6982:20;;;6960:42;;7030:17;;;;;;;:27;;6982:20;;6960:9;7030:27;;6982:20;;7030:27;:::i;:::-;;;;;;;;6698:370;;;6693:3;;;;:::i;:::-;;;6657:411;;;;7113:2;-1:-1:-1;;;;;7083:47:3;7107:4;-1:-1:-1;;;;;7083:47:3;7097:8;-1:-1:-1;;;;;7083:47:3;;7117:3;7122:7;7083:47;;;;;;;:::i;:::-;;;;;;;;7211:75;7247:8;7257:4;7263:2;7267:3;7272:7;7281:4;7211:35;:75::i;:::-;6366:927;6178:1115;;;;;:::o;2336:287:14:-;1759:1;2468:7;;:19;2460:63;;;;-1:-1:-1;;;2460:63:14;;28829:2:17;2460:63:14;;;28811:21:17;28868:2;28848:18;;;28841:30;28907:33;28887:18;;;28880:61;28958:18;;2460:63:14;28627:355:17;2460:63:14;1759:1;2598:7;:18;2336:287::o;10751:786:3:-;-1:-1:-1;;;;;10873:18:3;;10865:66;;;;-1:-1:-1;;;10865:66:3;;29189:2:17;10865:66:3;;;29171:21:17;29228:2;29208:18;;;29201:30;29267:34;29247:18;;;29240:62;-1:-1:-1;;;29318:18:17;;;29311:33;29361:19;;10865:66:3;28987:399:17;10865:66:3;719:10:1;10942:16:3;11006:21;11024:2;11006:17;:21::i;:::-;10983:44;;11037:24;11064:25;11082:6;11064:17;:25::i;:::-;11100:66;;;;;;;;;-1:-1:-1;11100:66:3;;;;11199:13;;;;;;;;;-1:-1:-1;;;;;11199:19:3;;;;;;;;11037:52;;-1:-1:-1;11236:21:3;;;;11228:70;;;;-1:-1:-1;;;11228:70:3;;29593:2:17;11228:70:3;;;29575:21:17;29632:2;29612:18;;;29605:30;29671:34;29651:18;;;29644:62;-1:-1:-1;;;29722:18:17;;;29715:34;29766:19;;11228:70:3;29391:400:17;11228:70:3;11332:9;:13;;;;;;;;;;;-1:-1:-1;;;;;11332:19:3;;;;;;;;;;;;11354:20;;;11332:42;;11400:54;;29970:25:17;;;30011:18;;;30004:34;;;11332:19:3;;11400:54;;;;;;29943:18:17;11400:54:3;;;;;;;11465:65;;;;;;;;;11509:1;11465:65;;;10855:682;;;;10751:786;;;:::o;3660:227:2:-;3738:7;3758:17;3777:18;3799:27;3810:4;3816:9;3799:10;:27::i;:::-;3757:69;;;;3836:18;3848:5;3836:11;:18::i;2426:187:13:-;2518:6;;;-1:-1:-1;;;;;2534:17:13;;;-1:-1:-1;;;;;;2534:17:13;;;;;;;2566:40;;2518:6;;;2534:17;2518:6;;2566:40;;2499:16;;2566:40;2489:124;2426:187;:::o;12855:323:3:-;13005:8;-1:-1:-1;;;;;12996:17:3;:5;-1:-1:-1;;;;;12996:17:3;;12988:71;;;;-1:-1:-1;;;12988:71:3;;30636:2:17;12988:71:3;;;30618:21:17;30675:2;30655:18;;;30648:30;30714:34;30694:18;;;30687:62;-1:-1:-1;;;30765:18:17;;;30758:39;30814:19;;12988:71:3;30434:405:17;12988:71:3;-1:-1:-1;;;;;13069:25:3;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;13069:46:3;;;;;;;;;;13130:41;;1159::17;;;13130::3;;1132:18:17;13130:41:3;;;;;;;12855:323;;;:::o;2755:96:15:-;2813:7;2839:5;2843:1;2839;:5;:::i;:::-;2832:12;2755:96;-1:-1:-1;;;2755:96:15:o;8575:709:3:-;-1:-1:-1;;;;;8722:16:3;;8714:62;;;;-1:-1:-1;;;8714:62:3;;31046:2:17;8714:62:3;;;31028:21:17;31085:2;31065:18;;;31058:30;31124:34;31104:18;;;31097:62;-1:-1:-1;;;31175:18:17;;;31168:31;31216:19;;8714:62:3;30844:397:17;8714:62:3;719:10:1;8787:16:3;8851:21;8869:2;8851:17;:21::i;:::-;8828:44;;8882:24;8909:25;8927:6;8909:17;:25::i;:::-;8882:52;;9022:9;:13;;;;;;;;;;;-1:-1:-1;;;;;9022:17:3;;;;;;;;;:27;;9043:6;;9022:9;:27;;9043:6;;9022:27;:::i;:::-;;;;-1:-1:-1;;9064:52:3;;;29970:25:17;;;30026:2;30011:18;;30004:34;;;-1:-1:-1;;;;;9064:52:3;;;;9097:1;;9064:52;;;;;;29943:18:17;9064:52:3;;;;;;;9203:74;9234:8;9252:1;9256:2;9260;9264:6;9272:4;9203:30;:74::i;4885:947::-;-1:-1:-1;;;;;5066:16:3;;5058:66;;;;-1:-1:-1;;;5058:66:3;;;;;;;:::i;:::-;719:10:1;5135:16:3;5199:21;5217:2;5199:17;:21::i;:::-;5176:44;;5230:24;5257:25;5275:6;5257:17;:25::i;:::-;5230:52;;5364:19;5386:13;;;;;;;;;;;-1:-1:-1;;;;;5386:19:3;;;;;;;;;;5423:21;;;;5415:76;;;;-1:-1:-1;;;5415:76:3;;;;;;;:::i;:::-;5525:9;:13;;;;;;;;;;;-1:-1:-1;;;;;5525:19:3;;;;;;;;;;5547:20;;;5525:42;;5587:17;;;;;;;:27;;5547:20;;5525:9;5587:27;;5547:20;;5587:27;:::i;:::-;;;;-1:-1:-1;;5630:46:3;;;29970:25:17;;;30026:2;30011:18;;30004:34;;;-1:-1:-1;;;;;5630:46:3;;;;;;;;;;;;;;29943:18:17;5630:46:3;;;;;;;5757:68;5788:8;5798:4;5804:2;5808;5812:6;5820:4;5757:30;:68::i;:::-;5048:784;;;;4885:947;;;;;:::o;9889:890:12:-;9942:7;;-1:-1:-1;;;10017:15:12;;10013:99;;-1:-1:-1;;;10052:15:12;;;-1:-1:-1;10095:2:12;10085:12;10013:99;10138:6;10129:5;:15;10125:99;;10173:6;10164:15;;;-1:-1:-1;10207:2:12;10197:12;10125:99;10250:6;10241:5;:15;10237:99;;10285:6;10276:15;;;-1:-1:-1;10319:2:12;10309:12;10237:99;10362:5;10353;:14;10349:96;;10396:5;10387:14;;;-1:-1:-1;10429:1:12;10419:11;10349:96;10471:5;10462;:14;10458:96;;10505:5;10496:14;;;-1:-1:-1;10538:1:12;10528:11;10458:96;10580:5;10571;:14;10567:96;;10614:5;10605:14;;;-1:-1:-1;10647:1:12;10637:11;10567:96;10689:5;10680;:14;10676:64;;10724:1;10714:11;10766:6;9889:890;-1:-1:-1;;9889:890:12:o;16211:792:3:-;-1:-1:-1;;;;;16443:13:3;;1465:19:0;:23;16439:558:3;;16478:79;;-1:-1:-1;;;16478:79:3;;-1:-1:-1;;;;;16478:43:3;;;;;:79;;16522:8;;16532:4;;16538:3;;16543:7;;16552:4;;16478:79;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16478:79:3;;;;;;;;-1:-1:-1;;16478:79:3;;;;;;;;;;;;:::i;:::-;;;16474:513;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;16863:6;16856:14;;-1:-1:-1;;;16856:14:3;;;;;;;;:::i;16474:513::-;;;16910:62;;-1:-1:-1;;;16910:62:3;;33394:2:17;16910:62:3;;;33376:21:17;33433:2;33413:18;;;33406:30;33472:34;33452:18;;;33445:62;-1:-1:-1;;;33523:18:17;;;33516:50;33583:19;;16910:62:3;33192:416:17;16474:513:3;-1:-1:-1;;;;;;16636:60:3;;-1:-1:-1;;;16636:60:3;16632:157;;16720:50;;-1:-1:-1;;;16720:50:3;;;;;;;:::i;17009:193::-;17128:16;;;17142:1;17128:16;;;;;;;;;17075;;17103:22;;17128:16;;;;;;;;;;;;-1:-1:-1;17128:16:3;17103:41;;17165:7;17154:5;17160:1;17154:8;;;;;;;;:::i;:::-;;;;;;;;;;:18;17190:5;17009:193;-1:-1:-1;;17009:193:3:o;2144:730:2:-;2225:7;2234:12;2262:9;:16;2282:2;2262:22;2258:610;;2598:4;2583:20;;2577:27;2647:4;2632:20;;2626:27;2704:4;2689:20;;2683:27;2300:9;2675:36;2745:25;2756:4;2675:36;2577:27;2626;2745:10;:25::i;:::-;2738:32;;;;;;;;;2258:610;-1:-1:-1;2817:1:2;;-1:-1:-1;2821:35:2;2801:56;;569:511;646:20;637:5;:29;;;;;;;;:::i;:::-;;633:441;;569:511;:::o;633:441::-;742:29;733:5;:38;;;;;;;;:::i;:::-;;729:345;;787:34;;-1:-1:-1;;;787:34:2;;34356:2:17;787:34:2;;;34338:21:17;34395:2;34375:18;;;34368:30;34434:26;34414:18;;;34407:54;34478:18;;787:34:2;34154:348:17;729:345:2;851:35;842:5;:44;;;;;;;;:::i;:::-;;838:236;;902:41;;-1:-1:-1;;;902:41:2;;34709:2:17;902:41:2;;;34691:21:17;34748:2;34728:18;;;34721:30;34787:33;34767:18;;;34760:61;34838:18;;902:41:2;34507:355:17;838:236:2;973:30;964:5;:39;;;;;;;;:::i;:::-;;960:114;;1019:44;;-1:-1:-1;;;1019:44:2;;35069:2:17;1019:44:2;;;35051:21:17;35108:2;35088:18;;;35081:30;35147:34;35127:18;;;35120:62;-1:-1:-1;;;35198:18:17;;;35191:32;35240:19;;1019:44:2;34867:398:17;15480:725:3;-1:-1:-1;;;;;15687:13:3;;1465:19:0;:23;15683:516:3;;15722:72;;-1:-1:-1;;;15722:72:3;;-1:-1:-1;;;;;15722:38:3;;;;;:72;;15761:8;;15771:4;;15777:2;;15781:6;;15789:4;;15722:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15722:72:3;;;;;;;;-1:-1:-1;;15722:72:3;;;;;;;;;;;;:::i;:::-;;;15718:471;;;;:::i;:::-;-1:-1:-1;;;;;;15843:55:3;;-1:-1:-1;;;15843:55:3;15839:152;;15922:50;;-1:-1:-1;;;15922:50:3;;;;;;;:::i;5068:1494:2:-;5194:7;;6118:66;6105:79;;6101:161;;;-1:-1:-1;6216:1:2;;-1:-1:-1;6220:30:2;6200:51;;6101:161;6373:24;;;6356:14;6373:24;;;;;;;;;36063:25:17;;;36136:4;36124:17;;36104:18;;;36097:45;;;;36158:18;;;36151:34;;;36201:18;;;36194:34;;;6373:24:2;;36035:19:17;;6373:24:2;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6373:24:2;;-1:-1:-1;;6373:24:2;;;-1:-1:-1;;;;;;;6411:20:2;;6407:101;;6463:1;6467:29;6447:50;;;;;;;6407:101;6526:6;-1:-1:-1;6534:20:2;;-1:-1:-1;5068:1494:2;;;;;;;;:::o;14:173:17:-;82:20;;-1:-1:-1;;;;;131:31:17;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:254::-;260:6;268;321:2;309:9;300:7;296:23;292:32;289:52;;;337:1;334;327:12;289:52;360:29;379:9;360:29;:::i;:::-;350:39;436:2;421:18;;;;408:32;;-1:-1:-1;;;192:254:17:o;633:131::-;-1:-1:-1;;;;;;707:32:17;;697:43;;687:71;;754:1;751;744:12;769:245;827:6;880:2;868:9;859:7;855:23;851:32;848:52;;;896:1;893;886:12;848:52;935:9;922:23;954:30;978:5;954:30;:::i;1211:366::-;1278:6;1286;1339:2;1327:9;1318:7;1314:23;1310:32;1307:52;;;1355:1;1352;1345:12;1307:52;1378:29;1397:9;1378:29;:::i;:::-;1368:39;;1457:2;1446:9;1442:18;1429:32;-1:-1:-1;;;;;1494:5:17;1490:38;1483:5;1480:49;1470:77;;1543:1;1540;1533:12;1470:77;1566:5;1556:15;;;1211:366;;;;;:::o;1582:250::-;1667:1;1677:113;1691:6;1688:1;1685:13;1677:113;;;1767:11;;;1761:18;1748:11;;;1741:39;1713:2;1706:10;1677:113;;;-1:-1:-1;;1824:1:17;1806:16;;1799:27;1582:250::o;1837:271::-;1879:3;1917:5;1911:12;1944:6;1939:3;1932:19;1960:76;2029:6;2022:4;2017:3;2013:14;2006:4;1999:5;1995:16;1960:76;:::i;:::-;2090:2;2069:15;-1:-1:-1;;2065:29:17;2056:39;;;;2097:4;2052:50;;1837:271;-1:-1:-1;;1837:271:17:o;2113:220::-;2262:2;2251:9;2244:21;2225:4;2282:45;2323:2;2312:9;2308:18;2300:6;2282:45;:::i;2338:180::-;2397:6;2450:2;2438:9;2429:7;2425:23;2421:32;2418:52;;;2466:1;2463;2456:12;2418:52;-1:-1:-1;2489:23:17;;2338:180;-1:-1:-1;2338:180:17:o;2523:635::-;2702:2;2691:9;2684:21;2747:6;2741:13;2736:2;2725:9;2721:18;2714:41;2665:4;2802:2;2794:6;2790:15;2784:22;2842:4;2837:2;2826:9;2822:18;2815:32;2870:52;2917:3;2906:9;2902:19;2888:12;2870:52;:::i;:::-;2856:66;;2976:2;2968:6;2964:15;2958:22;2953:2;2942:9;2938:18;2931:50;3036:2;3028:6;3024:15;3018:22;3012:3;3001:9;2997:19;2990:51;3125:1;3121;3116:3;3112:11;3108:19;3101:3;3093:6;3089:16;3083:23;3079:49;3072:4;3061:9;3057:20;3050:79;3146:6;3138:14;;;2523:635;;;;:::o;3163:248::-;3231:6;3239;3292:2;3280:9;3271:7;3267:23;3263:32;3260:52;;;3308:1;3305;3298:12;3260:52;-1:-1:-1;;3331:23:17;;;3401:2;3386:18;;;3373:32;;-1:-1:-1;3163:248:17:o;3695:533::-;3956:6;3945:9;3938:25;3999:3;3994:2;3983:9;3979:18;3972:31;3919:4;4020:46;4061:3;4050:9;4046:19;4038:6;4020:46;:::i;:::-;4097:2;4082:18;;4075:34;;;;-1:-1:-1;4140:2:17;4125:18;;4118:34;;;;-1:-1:-1;;;;;4189:32:17;4183:3;4168:19;;;4161:61;4012:54;3695:533;-1:-1:-1;;3695:533:17:o;4233:127::-;4294:10;4289:3;4285:20;4282:1;4275:31;4325:4;4322:1;4315:15;4349:4;4346:1;4339:15;4365:249;4475:2;4456:13;;-1:-1:-1;;4452:27:17;4440:40;;-1:-1:-1;;;;;4495:34:17;;4531:22;;;4492:62;4489:88;;;4557:18;;:::i;:::-;4593:2;4586:22;-1:-1:-1;;4365:249:17:o;4619:183::-;4679:4;-1:-1:-1;;;;;4704:6:17;4701:30;4698:56;;;4734:18;;:::i;:::-;-1:-1:-1;4779:1:17;4775:14;4791:4;4771:25;;4619:183::o;4807:724::-;4861:5;4914:3;4907:4;4899:6;4895:17;4891:27;4881:55;;4932:1;4929;4922:12;4881:55;4968:6;4955:20;4994:4;5017:43;5057:2;5017:43;:::i;:::-;5089:2;5083:9;5101:31;5129:2;5121:6;5101:31;:::i;:::-;5167:18;;;5259:1;5255:10;;;;5243:23;;5239:32;;;5201:15;;;;-1:-1:-1;5283:15:17;;;5280:35;;;5311:1;5308;5301:12;5280:35;5347:2;5339:6;5335:15;5359:142;5375:6;5370:3;5367:15;5359:142;;;5441:17;;5429:30;;5479:12;;;;5392;;5359:142;;;-1:-1:-1;5519:6:17;4807:724;-1:-1:-1;;;;;;4807:724:17:o;5536:555::-;5578:5;5631:3;5624:4;5616:6;5612:17;5608:27;5598:55;;5649:1;5646;5639:12;5598:55;5685:6;5672:20;-1:-1:-1;;;;;5707:2:17;5704:26;5701:52;;;5733:18;;:::i;:::-;5782:2;5776:9;5794:67;5849:2;5830:13;;-1:-1:-1;;5826:27:17;5855:4;5822:38;5776:9;5794:67;:::i;:::-;5885:2;5877:6;5870:18;5931:3;5924:4;5919:2;5911:6;5907:15;5903:26;5900:35;5897:55;;;5948:1;5945;5938:12;5897:55;6012:2;6005:4;5997:6;5993:17;5986:4;5978:6;5974:17;5961:54;6059:1;6035:15;;;6052:4;6031:26;6024:37;;;;6039:6;5536:555;-1:-1:-1;;;5536:555:17:o;6096:943::-;6250:6;6258;6266;6274;6282;6335:3;6323:9;6314:7;6310:23;6306:33;6303:53;;;6352:1;6349;6342:12;6303:53;6375:29;6394:9;6375:29;:::i;:::-;6365:39;;6423:38;6457:2;6446:9;6442:18;6423:38;:::i;:::-;6413:48;;6512:2;6501:9;6497:18;6484:32;-1:-1:-1;;;;;6576:2:17;6568:6;6565:14;6562:34;;;6592:1;6589;6582:12;6562:34;6615:61;6668:7;6659:6;6648:9;6644:22;6615:61;:::i;:::-;6605:71;;6729:2;6718:9;6714:18;6701:32;6685:48;;6758:2;6748:8;6745:16;6742:36;;;6774:1;6771;6764:12;6742:36;6797:63;6852:7;6841:8;6830:9;6826:24;6797:63;:::i;:::-;6787:73;;6913:3;6902:9;6898:19;6885:33;6869:49;;6943:2;6933:8;6930:16;6927:36;;;6959:1;6956;6949:12;6927:36;;6982:51;7025:7;7014:8;7003:9;6999:24;6982:51;:::i;:::-;6972:61;;;6096:943;;;;;;;;:::o;7044:254::-;7112:6;7120;7173:2;7161:9;7152:7;7148:23;7144:32;7141:52;;;7189:1;7186;7179:12;7141:52;7225:9;7212:23;7202:33;;7254:38;7288:2;7277:9;7273:18;7254:38;:::i;:::-;7244:48;;7044:254;;;;;:::o;7303:160::-;7368:20;;7424:13;;7417:21;7407:32;;7397:60;;7453:1;7450;7443:12;7468:180;7524:6;7577:2;7565:9;7556:7;7552:23;7548:32;7545:52;;;7593:1;7590;7583:12;7545:52;7616:26;7632:9;7616:26;:::i;7653:1208::-;7771:6;7779;7832:2;7820:9;7811:7;7807:23;7803:32;7800:52;;;7848:1;7845;7838:12;7800:52;7888:9;7875:23;-1:-1:-1;;;;;7958:2:17;7950:6;7947:14;7944:34;;;7974:1;7971;7964:12;7944:34;8012:6;8001:9;7997:22;7987:32;;8057:7;8050:4;8046:2;8042:13;8038:27;8028:55;;8079:1;8076;8069:12;8028:55;8115:2;8102:16;8137:4;8160:43;8200:2;8160:43;:::i;:::-;8232:2;8226:9;8244:31;8272:2;8264:6;8244:31;:::i;:::-;8310:18;;;8398:1;8394:10;;;;8386:19;;8382:28;;;8344:15;;;;-1:-1:-1;8422:19:17;;;8419:39;;;8454:1;8451;8444:12;8419:39;8478:11;;;;8498:148;8514:6;8509:3;8506:15;8498:148;;;8580:23;8599:3;8580:23;:::i;:::-;8568:36;;8531:12;;;;8624;;;;8498:148;;;8665:6;-1:-1:-1;;8709:18:17;;8696:32;;-1:-1:-1;;8740:16:17;;;8737:36;;;8769:1;8766;8759:12;8737:36;;8792:63;8847:7;8836:8;8825:9;8821:24;8792:63;:::i;:::-;8782:73;;;7653:1208;;;;;:::o;8866:435::-;8919:3;8957:5;8951:12;8984:6;8979:3;8972:19;9010:4;9039:2;9034:3;9030:12;9023:19;;9076:2;9069:5;9065:14;9097:1;9107:169;9121:6;9118:1;9115:13;9107:169;;;9182:13;;9170:26;;9216:12;;;;9251:15;;;;9143:1;9136:9;9107:169;;;-1:-1:-1;9292:3:17;;8866:435;-1:-1:-1;;;;;8866:435:17:o;9306:261::-;9485:2;9474:9;9467:21;9448:4;9505:56;9557:2;9546:9;9542:18;9534:6;9505:56;:::i;9572:321::-;9641:6;9694:2;9682:9;9673:7;9669:23;9665:32;9662:52;;;9710:1;9707;9700:12;9662:52;9750:9;9737:23;-1:-1:-1;;;;;9775:6:17;9772:30;9769:50;;;9815:1;9812;9805:12;9769:50;9838:49;9879:7;9870:6;9859:9;9855:22;9838:49;:::i;:::-;9828:59;9572:321;-1:-1:-1;;;;9572:321:17:o;9898:752::-;10012:6;10020;10028;10036;10044;10097:3;10085:9;10076:7;10072:23;10068:33;10065:53;;;10114:1;10111;10104:12;10065:53;10137:29;10156:9;10137:29;:::i;:::-;10127:39;;10213:2;10202:9;10198:18;10185:32;10175:42;;10264:2;10253:9;10249:18;10236:32;10226:42;;10319:2;10308:9;10304:18;10291:32;-1:-1:-1;;;;;10383:2:17;10375:6;10372:14;10369:34;;;10399:1;10396;10389:12;10369:34;10422:49;10463:7;10454:6;10443:9;10439:22;10422:49;:::i;10655:186::-;10714:6;10767:2;10755:9;10746:7;10742:23;10738:32;10735:52;;;10783:1;10780;10773:12;10735:52;10806:29;10825:9;10806:29;:::i;11054:389::-;11132:6;11140;11193:2;11181:9;11172:7;11168:23;11164:32;11161:52;;;11209:1;11206;11199:12;11161:52;11245:9;11232:23;11222:33;;11306:2;11295:9;11291:18;11278:32;-1:-1:-1;;;;;11325:6:17;11322:30;11319:50;;;11365:1;11362;11355:12;11319:50;11388:49;11429:7;11420:6;11409:9;11405:22;11388:49;:::i;11448:254::-;11513:6;11521;11574:2;11562:9;11553:7;11549:23;11545:32;11542:52;;;11590:1;11587;11580:12;11542:52;11613:29;11632:9;11613:29;:::i;:::-;11603:39;;11661:35;11692:2;11681:9;11677:18;11661:35;:::i;12032:677::-;12137:6;12145;12153;12161;12214:3;12202:9;12193:7;12189:23;12185:33;12182:53;;;12231:1;12228;12221:12;12182:53;12267:9;12254:23;12244:33;;12324:2;12313:9;12309:18;12296:32;12286:42;;12379:2;12368:9;12364:18;12351:32;-1:-1:-1;;;;;12443:2:17;12435:6;12432:14;12429:34;;;12459:1;12456;12449:12;12429:34;12482:49;12523:7;12514:6;12503:9;12499:22;12482:49;:::i;:::-;12472:59;;12584:2;12573:9;12569:18;12556:32;12540:48;;12613:2;12603:8;12600:16;12597:36;;;12629:1;12626;12619:12;12597:36;;12652:51;12695:7;12684:8;12673:9;12669:24;12652:51;:::i;:::-;12642:61;;;12032:677;;;;;;;:::o;12714:532::-;12810:6;12818;12826;12834;12887:3;12875:9;12866:7;12862:23;12858:33;12855:53;;;12904:1;12901;12894:12;12855:53;12940:9;12927:23;12917:33;;13001:2;12990:9;12986:18;12973:32;-1:-1:-1;;;;;13020:6:17;13017:30;13014:50;;;13060:1;13057;13050:12;13014:50;13083:49;13124:7;13115:6;13104:9;13100:22;13083:49;:::i;:::-;13073:59;;;13179:2;13168:9;13164:18;13151:32;13141:42;;13202:38;13236:2;13225:9;13221:18;13202:38;:::i;:::-;13192:48;;12714:532;;;;;;;:::o;13251:260::-;13319:6;13327;13380:2;13368:9;13359:7;13355:23;13351:32;13348:52;;;13396:1;13393;13386:12;13348:52;13419:29;13438:9;13419:29;:::i;:::-;13409:39;;13467:38;13501:2;13490:9;13486:18;13467:38;:::i;13516:606::-;13620:6;13628;13636;13644;13652;13705:3;13693:9;13684:7;13680:23;13676:33;13673:53;;;13722:1;13719;13712:12;13673:53;13745:29;13764:9;13745:29;:::i;:::-;13735:39;;13793:38;13827:2;13816:9;13812:18;13793:38;:::i;:::-;13783:48;;13878:2;13867:9;13863:18;13850:32;13840:42;;13929:2;13918:9;13914:18;13901:32;13891:42;;13984:3;13973:9;13969:19;13956:33;-1:-1:-1;;;;;14004:6:17;14001:30;13998:50;;;14044:1;14041;14034:12;13998:50;14067:49;14108:7;14099:6;14088:9;14084:22;14067:49;:::i;14538:380::-;14617:1;14613:12;;;;14660;;;14681:61;;14735:4;14727:6;14723:17;14713:27;;14681:61;14788:2;14780:6;14777:14;14757:18;14754:38;14751:161;;14834:10;14829:3;14825:20;14822:1;14815:31;14869:4;14866:1;14859:15;14897:4;14894:1;14887:15;14751:161;;14538:380;;;:::o;15409:722::-;15459:3;15500:5;15494:12;15529:36;15555:9;15529:36;:::i;:::-;15584:1;15601:18;;;15628:133;;;;15775:1;15770:355;;;;15594:531;;15628:133;-1:-1:-1;;15661:24:17;;15649:37;;15734:14;;15727:22;15715:35;;15706:45;;;-1:-1:-1;15628:133:17;;15770:355;15801:5;15798:1;15791:16;15830:4;15875:2;15872:1;15862:16;15900:1;15914:165;15928:6;15925:1;15922:13;15914:165;;;16006:14;;15993:11;;;15986:35;16049:16;;;;15943:10;;15914:165;;;15918:3;;;16108:6;16103:3;16099:16;16092:23;;15594:531;;;;;15409:722;;;;:::o;16136:469::-;16357:3;16385:38;16419:3;16411:6;16385:38;:::i;:::-;16452:6;16446:13;16468:65;16526:6;16522:2;16515:4;16507:6;16503:17;16468:65;:::i;:::-;16549:50;16591:6;16587:2;16583:15;16575:6;16549:50;:::i;:::-;16542:57;16136:469;-1:-1:-1;;;;;;;16136:469:17:o;16957:127::-;17018:10;17013:3;17009:20;17006:1;16999:31;17049:4;17046:1;17039:15;17073:4;17070:1;17063:15;17089:168;17162:9;;;17193;;17210:15;;;17204:22;;17190:37;17180:71;;17231:18;;:::i;17394:217::-;17434:1;17460;17450:132;;17504:10;17499:3;17495:20;17492:1;17485:31;17539:4;17536:1;17529:15;17567:4;17564:1;17557:15;17450:132;-1:-1:-1;17596:9:17;;17394:217::o;17616:410::-;17818:2;17800:21;;;17857:2;17837:18;;;17830:30;17896:34;17891:2;17876:18;;17869:62;-1:-1:-1;;;17962:2:17;17947:18;;17940:44;18016:3;18001:19;;17616:410::o;19552:127::-;19613:10;19608:3;19604:20;19601:1;19594:31;19644:4;19641:1;19634:15;19668:4;19665:1;19658:15;19684:135;19723:3;19744:17;;;19741:43;;19764:18;;:::i;:::-;-1:-1:-1;19811:1:17;19800:13;;19684:135::o;19824:545::-;19926:2;19921:3;19918:11;19915:448;;;19962:1;19987:5;19983:2;19976:17;20032:4;20028:2;20018:19;20102:2;20090:10;20086:19;20083:1;20079:27;20073:4;20069:38;20138:4;20126:10;20123:20;20120:47;;;-1:-1:-1;20161:4:17;20120:47;20216:2;20211:3;20207:12;20204:1;20200:20;20194:4;20190:31;20180:41;;20271:82;20289:2;20282:5;20279:13;20271:82;;;20334:17;;;20315:1;20304:13;20271:82;;20545:1352;20671:3;20665:10;-1:-1:-1;;;;;20690:6:17;20687:30;20684:56;;;20720:18;;:::i;:::-;20749:97;20839:6;20799:38;20831:4;20825:11;20799:38;:::i;:::-;20793:4;20749:97;:::i;:::-;20901:4;;20965:2;20954:14;;20982:1;20977:663;;;;21684:1;21701:6;21698:89;;;-1:-1:-1;21753:19:17;;;21747:26;21698:89;-1:-1:-1;;20502:1:17;20498:11;;;20494:24;20490:29;20480:40;20526:1;20522:11;;;20477:57;21800:81;;20947:944;;20977:663;15356:1;15349:14;;;15393:4;15380:18;;-1:-1:-1;;21013:20:17;;;21131:236;21145:7;21142:1;21139:14;21131:236;;;21234:19;;;21228:26;21213:42;;21326:27;;;;21294:1;21282:14;;;;21161:19;;21131:236;;;21135:3;21395:6;21386:7;21383:19;21380:201;;;21456:19;;;21450:26;-1:-1:-1;;21539:1:17;21535:14;;;21551:3;21531:24;21527:37;21523:42;21508:58;21493:74;;21380:201;-1:-1:-1;;;;;21627:1:17;21611:14;;;21607:22;21594:36;;-1:-1:-1;20545:1352:17:o;21902:540::-;-1:-1:-1;;;;;22168:31:17;22159:6;22155:2;22151:15;22147:53;22142:3;22135:66;22231:6;22226:2;22221:3;22217:12;22210:28;22268:6;22263:2;22258:3;22254:12;22247:28;22117:3;22304:6;22298:13;22320:75;22388:6;22383:2;22378:3;22374:12;22367:4;22359:6;22355:17;22320:75;:::i;:::-;22415:16;;;;22433:2;22411:25;;21902:540;-1:-1:-1;;;;;21902:540:17:o;23158:287::-;23287:3;23325:6;23319:13;23341:66;23400:6;23395:3;23388:4;23380:6;23376:17;23341:66;:::i;:::-;23423:16;;;;;23158:287;-1:-1:-1;;23158:287:17:o;27210:401::-;27412:2;27394:21;;;27451:2;27431:18;;;27424:30;27490:34;27485:2;27470:18;;27463:62;-1:-1:-1;;;27556:2:17;27541:18;;27534:35;27601:3;27586:19;;27210:401::o;27616:406::-;27818:2;27800:21;;;27857:2;27837:18;;;27830:30;27896:34;27891:2;27876:18;;27869:62;-1:-1:-1;;;27962:2:17;27947:18;;27940:40;28012:3;27997:19;;27616:406::o;28027:125::-;28092:9;;;28113:10;;;28110:36;;;28126:18;;:::i;28157:465::-;28414:2;28403:9;28396:21;28377:4;28440:56;28492:2;28481:9;28477:18;28469:6;28440:56;:::i;:::-;28544:9;28536:6;28532:22;28527:2;28516:9;28512:18;28505:50;28572:44;28609:6;28601;28572:44;:::i;:::-;28564:52;28157:465;-1:-1:-1;;;;;28157:465:17:o;31246:827::-;-1:-1:-1;;;;;31643:15:17;;;31625:34;;31695:15;;31690:2;31675:18;;31668:43;31605:3;31742:2;31727:18;;31720:31;;;31568:4;;31774:57;;31811:19;;31803:6;31774:57;:::i;:::-;31879:9;31871:6;31867:22;31862:2;31851:9;31847:18;31840:50;31913:44;31950:6;31942;31913:44;:::i;:::-;31899:58;;32006:9;31998:6;31994:22;31988:3;31977:9;31973:19;31966:51;32034:33;32060:6;32052;32034:33;:::i;:::-;32026:41;31246:827;-1:-1:-1;;;;;;;;31246:827:17:o;32078:249::-;32147:6;32200:2;32188:9;32179:7;32175:23;32171:32;32168:52;;;32216:1;32213;32206:12;32168:52;32248:9;32242:16;32267:30;32291:5;32267:30;:::i;32332:179::-;32367:3;32409:1;32391:16;32388:23;32385:120;;;32455:1;32452;32449;32434:23;-1:-1:-1;32492:1:17;32486:8;32481:3;32477:18;32385:120;32332:179;:::o;32516:671::-;32555:3;32597:4;32579:16;32576:26;32573:39;;;32516:671;:::o;32573:39::-;32639:2;32633:9;-1:-1:-1;;32704:16:17;32700:25;;32697:1;32633:9;32676:50;32755:4;32749:11;32779:16;-1:-1:-1;;;;;32885:2:17;32878:4;32870:6;32866:17;32863:25;32858:2;32850:6;32847:14;32844:45;32841:58;;;32892:5;;;;;32516:671;:::o;32841:58::-;32929:6;32923:4;32919:17;32908:28;;32965:3;32959:10;32992:2;32984:6;32981:14;32978:27;;;32998:5;;;;;;32516:671;:::o;32978:27::-;33082:2;33063:16;33057:4;33053:27;33049:36;33042:4;33033:6;33028:3;33024:16;33020:27;33017:69;33014:82;;;33089:5;;;;;;32516:671;:::o;33014:82::-;33105:57;33156:4;33147:6;33139;33135:19;33131:30;33125:4;33105:57;:::i;:::-;-1:-1:-1;33178:3:17;;32516:671;-1:-1:-1;;;;;32516:671:17:o;33613:404::-;33815:2;33797:21;;;33854:2;33834:18;;;33827:30;33893:34;33888:2;33873:18;;33866:62;-1:-1:-1;;;33959:2:17;33944:18;;33937:38;34007:3;33992:19;;33613:404::o;34022:127::-;34083:10;34078:3;34074:20;34071:1;34064:31;34114:4;34111:1;34104:15;34138:4;34135:1;34128:15;35270:561;-1:-1:-1;;;;;35567:15:17;;;35549:34;;35619:15;;35614:2;35599:18;;35592:43;35666:2;35651:18;;35644:34;;;35709:2;35694:18;;35687:34;;;35529:3;35752;35737:19;;35730:32;;;35492:4;;35779:46;;35805:19;;35797:6;35779:46;:::i

Swarm Source

ipfs://34bc9d03e17f6657e7ef2d0ddf5dcd6aeee6a9aa70d580947dfebcc40044954c
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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