Token SandStorm

 

Overview

TokenID:
1503

Transfers:
-

 
Loading
[ Download CSV Export  ] 
Loading
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
SandStorm

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, Unlicense license

Contract Source Code (Solidity)

/**
 *Submitted for verification at PolygonScan.com on 2022-02-14
*/

// SPDX-License-Identifier:UNLICENSED
pragma solidity ^0.8.4;

library Strings {

    function toString(uint256 value) internal pure returns (string memory) {

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

library EnumerableMap {

    struct MapEntry {
        bytes32 _key;
        bytes32 _value;
    }

    struct Map {
        MapEntry[] _entries;

        mapping (bytes32 => uint256) _indexes;
    }

    function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {
        uint256 keyIndex = map._indexes[key];

        if (keyIndex == 0) { // Equivalent to !contains(map, key)
            map._entries.push(MapEntry({ _key: key, _value: value }));
            map._indexes[key] = map._entries.length;
            return true;
        } else {
            map._entries[keyIndex - 1]._value = value;
            return false;
        }
    }

    function _remove(Map storage map, bytes32 key) private returns (bool) {
        uint256 keyIndex = map._indexes[key];

        if (keyIndex != 0) { // Equivalent to contains(map, key)
            uint256 toDeleteIndex = keyIndex - 1;
            uint256 lastIndex = map._entries.length - 1;
            MapEntry storage lastEntry = map._entries[lastIndex];

            map._entries[toDeleteIndex] = lastEntry;
            map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based

            map._entries.pop();

            delete map._indexes[key];

            return true;
        } else {
            return false;
        }
    }

    function _contains(Map storage map, bytes32 key) private view returns (bool) {
        return map._indexes[key] != 0;
    }

    function _length(Map storage map) private view returns (uint256) {
        return map._entries.length;
    }

    function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {
        require(map._entries.length > index, "EnumerableMap: index out of bounds");

        MapEntry storage entry = map._entries[index];
        return (entry._key, entry._value);
    }

    function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {
        uint256 keyIndex = map._indexes[key];
        if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)
        return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based
    }

    function _get(Map storage map, bytes32 key) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    struct UintToAddressMap {
        Map _inner;
    }

    function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {
        return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
    }

    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
        return _remove(map._inner, bytes32(key));
    }

    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
        return _contains(map._inner, bytes32(key));
    }

    function length(UintToAddressMap storage map) internal view returns (uint256) {
        return _length(map._inner);
    }

    function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
        (bytes32 key, bytes32 value) = _at(map._inner, index);
        return (uint256(key), address(uint160(uint256(value))));
    }

    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
        (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));
        return (success, address(uint160(uint256(value))));
    }

    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
        return address(uint160(uint256(_get(map._inner, bytes32(key)))));
    }

    function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {
        return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));
    }
}

library EnumerableSet {
    struct Set {
        bytes32[] _values;
        mapping (bytes32 => uint256) _indexes;
    }

    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    function _remove(Set storage set, bytes32 value) private returns (bool) {
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) { // Equivalent to contains(set, value)
            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;
            bytes32 lastvalue = set._values[lastIndex];

            set._values[toDeleteIndex] = lastvalue;
            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based

            set._values.pop();

            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        require(set._values.length > index, "EnumerableSet: index out of bounds");
        return set._values[index];
    }

    struct Bytes32Set {
        Set _inner;
    }

    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    struct AddressSet {
        Set _inner;
    }

    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    struct UintSet {
        Set _inner;
    }

    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }
}

library Address {

    function isContract(address account) internal view returns (bool) {
        uint256 size;
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    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");
    }

    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    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");
    }

    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

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

    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

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

    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

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

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            if (returndata.length > 0) {
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
} 

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

abstract contract ERC165 is IERC165 {

    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor () {
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

interface IERC721 is IERC165 {

    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    event URI(string value, uint256 indexed id);

    event tokenBaseURI(string value);

    function balanceOf(address owner) external view returns (uint256 balance);

    function royaltyFee(uint256 tokenId) external view  returns(uint256);
        
    function getCreator(uint256 tokenId) external view returns(address);

    function ownerOf(uint256 tokenId) external view returns (address owner);

    function safeTransferFrom(address from, address to, uint256 tokenId) external;

    function transferFrom(address from, address to, uint256 tokenId) external;

    function approve(address to, uint256 tokenId) external;

    function getApproved(uint256 tokenId) external view returns (address operator);

    function setApprovalForAll(address operator, bool _approved) external;

    function isApprovedForAll(address owner, address operator) external view returns (bool);

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}


interface IERC721Receiver {

    function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
}

interface IERC721Enumerable is IERC721 {

    function totalSupply() external view returns (uint256);

    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

    function tokenByIndex(uint256 index) external view returns (uint256);
}

interface IERC721Metadata is IERC721 {

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function tokenURI(uint256 tokenId) external view returns (string memory);
}

abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return payable(msg.sender);
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {
    using Address for address;
    using EnumerableSet for EnumerableSet.UintSet;
    using EnumerableMap for EnumerableMap.UintToAddressMap;
    using Strings for uint256;

    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

    // Mapping from token ID to account balances

    mapping (address => EnumerableSet.UintSet) private _holderTokens;

    EnumerableMap.UintToAddressMap private _tokenOwners;

     // Mapping from tokenId to operator approvals

    mapping (uint256 => address) private _tokenApprovals;

    // Mapping from account to operator approvals

    mapping (address => mapping (address => bool)) private _operatorApprovals;

    string private _name;

    string private _symbol;

    // mapping for token URIs

    mapping (uint256 => string) private _tokenURIs;

   // mapping for token royaltyFee    

    mapping(uint256 => uint256) private _royaltyFee;

  // mapping for token creator

    mapping (uint256 => address) private _creator;

    string private _baseURI = "https://gateway.pinata.cloud/ipfs/";

    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;

    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;

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

        _registerInterface(_INTERFACE_ID_ERC721);
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
    }

    /**
        @notice Get the Token balance of an account's.
        @param owner  The address of the token holder
        @return        The account's balance of the Token type requested
     */

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

    /**
        @notice Get the owner of tokenId.
        @param tokenId  The tokenId of the token holder
        @return        The current owner of the requested tokenId
     */

    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token");
    }

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

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

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = baseURI();

        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }
        return string(abi.encodePacked(base, tokenId.toString()));
    }

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

    function royaltyFee(uint256 tokenId) public view override returns(uint256) {
        return _royaltyFee[tokenId];
    }

    function getCreator(uint256 tokenId) public view override returns(address) {
        return _creator[tokenId];
    }

    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        return _holderTokens[owner].at(index);
    }

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

    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        (uint256 tokenId, ) = _tokenOwners.at(index);
        return tokenId;
    }

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

    /**
        @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens.
        @dev MUST emit the ApprovalForAll event on success.
        @param operator  Address to add to the set of authorized operators
        @param approved  True if the operator is approved, false to revoke approval
    */

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

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

    /**
        @notice Queries the approval status of an operator for a given owner.
        @param owner     The owner of the Tokens
        @param operator  Address of authorized operator
        @return           True if the operator is approved, false if not
    */

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

    function transferFrom(address from, address to, uint256 tokenId) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

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


    /**
        @notice Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call).
        @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard).
        MUST revert if `_to` is the zero address.
        MUST revert if balance of holder for token `_id` is lower than the `_value` sent.
        MUST revert on any other error.
        MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard).
        After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
        @param from    Source address
        @param to      Target address
        @param tokenId      ID of the token type.
        @param _data    Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to`
    */

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

    }

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

    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _tokenOwners.contains(tokenId);
    }

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

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

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

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

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

        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);
        _creator[tokenId] = msg.sender;
        _royaltyFee[tokenId] = fee;

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

     /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use {ERC721-_burn} instead.
     * required msg.sender must be owner of the token.
     * @param tokenId uint256 Token being burned
     */

    function _burn(uint256 tokenId) internal virtual {
        require(msg.sender == ownerOf(tokenId),"caller not owner");
        address owner = ERC721.ownerOf(tokenId); // internal owner

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

        _approve(address(0), tokenId);

        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }

        _holderTokens[owner].remove(tokenId);

        _tokenOwners.remove(tokenId);

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

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

        _beforeTokenTransfer(from, to, tokenId);

        _approve(address(0), tokenId);

        _holderTokens[from].remove(tokenId);
        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

        emit Transfer(from, to, tokenId);
    }

     /**
     * @dev Internal function to set the token URI for a given token.
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to set its URI
     * @param _tokenURI string URI to assign
     */

    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
         emit URI(_tokenURI, tokenId);
    }

    function _setBaseURI(string memory baseURI_) internal virtual {
        _baseURI = baseURI_;
        emit tokenBaseURI(baseURI_);
    }

    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
        private returns (bool)
    {
        if (!to.isContract()) {
            return true;
        }
        bytes memory returndata = to.functionCall(abi.encodeWithSelector(
            IERC721Receiver(to).onERC721Received.selector,
            _msgSender(),
            from,
            tokenId,
            _data
        ), "ERC721: transfer to non ERC721Receiver implementer");
        bytes4 retval = abi.decode(returndata, (bytes4));
        return (retval == _ERC721_RECEIVED);
    }

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

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

contract SandStorm is ERC721 {
    uint256 public tokenCounter;
    address public owner;
    mapping(uint256 => bool) private usedNonce;


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

    struct Sign {
        uint8 v;
        bytes32 r;
        bytes32 s;
        uint256 nonce;
    }

    constructor (string memory name, string memory symbol) ERC721 (name, symbol){
        tokenCounter = 1;
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(owner == msg.sender, "Ownable: caller is not the owner");
        _;
    }

    function transferOwnership(address newOwner) external onlyOwner returns(bool){
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        owner = newOwner;
        emit OwnershipTransferred(owner, newOwner);
        return true;
    }

    function verifySign(string memory tokenURI, address caller, Sign memory sign) internal view {
        bytes32 hash = keccak256(abi.encodePacked(this, caller, tokenURI, sign.nonce));
        require(owner == ecrecover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)), sign.v, sign.r, sign.s), "Owner sign verification failed");
    }

    
    /**
     * @dev Internal function to mint a new token.
     * Reverts if the given token ID already exists.
     * @param sign struct combination of uint8, bytes32, bytes32 are v, r, s.
     * @param tokenURI string memory URI of the token to be minted.
     * @param fee uint256 royalty of the token to be minted.
     */

    function createCollectible(string memory tokenURI, uint256 fee, Sign memory sign) external returns (uint256) {
        require(!usedNonce[sign.nonce], "Nonce : Invalid Nonce");
        usedNonce[sign.nonce] = true;
        uint256 newItemId = tokenCounter;
        verifySign(tokenURI, msg.sender, sign);
        _safeMint(msg.sender, newItemId, fee);
        _setTokenURI(newItemId, tokenURI);
        tokenCounter = tokenCounter + 1;
        return newItemId;
    }

    function setBaseURI(string memory _baseURI) external onlyOwner{
        _setBaseURI(_baseURI);
    }
    
    function burn(uint256 tokenId) external {
        require(_exists(tokenId), "ERC721: nonexistent token");
        _burn(tokenId);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"}],"name":"tokenBaseURI","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"tokenURI","type":"string"},{"internalType":"uint256","name":"fee","type":"uint256"},{"components":[{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"internalType":"struct SandStorm.Sign","name":"sign","type":"tuple"}],"name":"createCollectible","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getCreator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"royaltyFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

60e06040526022608081815290620028c160a03980516200002991600b9160209091019062000175565b503480156200003757600080fd5b50604051620028e3380380620028e38339810160408190526200005a91620002ce565b81816200006e6301ffc9a760e01b620000f1565b81516200008390600690602085019062000175565b5080516200009990600790602084019062000175565b50620000ac6380ac58cd60e01b620000f1565b620000be635b5e139f60e01b620000f1565b620000d063780e9d6360e01b620000f1565b50506001600c555050600d80546001600160a01b0319163317905562000388565b6001600160e01b03198082161415620001505760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640160405180910390fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b828054620001839062000335565b90600052602060002090601f016020900481019282620001a75760008555620001f2565b82601f10620001c257805160ff1916838001178555620001f2565b82800160010185558215620001f2579182015b82811115620001f2578251825591602001919060010190620001d5565b506200020092915062000204565b5090565b5b8082111562000200576000815560010162000205565b600082601f8301126200022c578081fd5b81516001600160401b038082111562000249576200024962000372565b604051601f8301601f19908116603f0116810190828211818310171562000274576200027462000372565b8160405283815260209250868385880101111562000290578485fd5b8491505b83821015620002b3578582018301518183018401529082019062000294565b83821115620002c457848385830101525b9695505050505050565b60008060408385031215620002e1578182fd5b82516001600160401b0380821115620002f8578384fd5b62000306868387016200021b565b935060208501519150808211156200031c578283fd5b506200032b858286016200021b565b9150509250929050565b600181811c908216806200034a57607f821691505b602082108114156200036c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b61252980620003986000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80636c0360eb116100de578063c57dc23511610097578063d1c58bdd11610071578063d1c58bdd14610342578063d48e638a14610355578063e985e9c51461037e578063f2fde38b146103ba57600080fd5b8063c57dc23514610306578063c87b56dd14610326578063d082e3811461033957600080fd5b80636c0360eb146102aa57806370a08231146102b25780638da5cb5b146102c557806395d89b41146102d8578063a22cb465146102e0578063b88d4fde146102f357600080fd5b80632f745c59116101305780632f745c591461023857806342842e0e1461024b57806342966c681461025e5780634f6ccce71461027157806355f804b3146102845780636352211e1461029757600080fd5b806301ffc9a71461017857806306fdde03146101ba578063081812fc146101cf578063095ea7b3146101fa57806318160ddd1461020f57806323b872dd14610225575b600080fd5b6101a56101863660046120a4565b6001600160e01b03191660009081526020819052604090205460ff1690565b60405190151581526020015b60405180910390f35b6101c26103cd565b6040516101b191906122c3565b6101e26101dd3660046121aa565b61045f565b6040516001600160a01b0390911681526020016101b1565b61020d61020836600461207b565b6104ec565b005b610217610602565b6040519081526020016101b1565b61020d610233366004611f8d565b610613565b61021761024636600461207b565b610644565b61020d610259366004611f8d565b61066f565b61020d61026c3660046121aa565b61068a565b61021761027f3660046121aa565b6106eb565b61020d6102923660046120dc565b610701565b6101e26102a53660046121aa565b610764565b6101c261078c565b6102176102c0366004611f41565b61079b565b600d546101e2906001600160a01b031681565b6101c2610827565b61020d6102ee366004612041565b610836565b61020d610301366004611fc8565b6108fb565b6102176103143660046121aa565b60009081526009602052604090205490565b6101c26103343660046121aa565b610933565b610217600c5481565b61021761035036600461210f565b610aa5565b6101e26103633660046121aa565b6000908152600a60205260409020546001600160a01b031690565b6101a561038c366004611f5b565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6101a56103c8366004611f41565b610b5d565b6060600680546103dc906123d6565b80601f0160208091040260200160405190810160405280929190818152602001828054610408906123d6565b80156104555780601f1061042a57610100808354040283529160200191610455565b820191906000526020600020905b81548152906001019060200180831161043857829003601f168201915b5050505050905090565b600061046a82610c71565b6104d05760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006104f782610764565b9050806001600160a01b0316836001600160a01b031614156105655760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016104c7565b336001600160a01b03821614806105815750610581813361038c565b6105f35760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016104c7565b6105fd8383610c7e565b505050565b600061060e6002610cec565b905090565b61061d3382610cf6565b6106395760405162461bcd60e51b81526004016104c7906122d6565b6105fd838383610de0565b6001600160a01b03821660009081526001602052604081206106669083610f61565b90505b92915050565b6105fd838383604051806020016040528060008152506108fb565b61069381610c71565b6106df5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a206e6f6e6578697374656e7420746f6b656e0000000000000060448201526064016104c7565b6106e881610f6d565b50565b6000806106f9600284611083565b509392505050565b600d546001600160a01b0316331461075b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c7565b6106e88161109f565b6000610669826040518060600160405280602981526020016124cb60299139600291906110ed565b6060600b80546103dc906123d6565b60006001600160a01b0382166108065760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016104c7565b6001600160a01b038216600090815260016020526040902061066990610cec565b6060600780546103dc906123d6565b6001600160a01b03821633141561088f5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016104c7565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6109053383610cf6565b6109215760405162461bcd60e51b81526004016104c7906122d6565b61092d848484846110fa565b50505050565b606061093e82610c71565b6109a25760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016104c7565b600082815260086020526040812080546109bb906123d6565b80601f01602080910402602001604051908101604052809291908181526020018280546109e7906123d6565b8015610a345780601f10610a0957610100808354040283529160200191610a34565b820191906000526020600020905b815481529060010190602001808311610a1757829003601f168201915b505050505090506000610a4561078c565b9050805160001415610a58575092915050565b815115610a8a578082604051602001610a72929190612257565b60405160208183030381529060405292505050919050565b80610a9485611178565b604051602001610a72929190612257565b60608101516000908152600e602052604081205460ff1615610b015760405162461bcd60e51b81526020600482015260156024820152744e6f6e6365203a20496e76616c6964204e6f6e636560581b60448201526064016104c7565b60608201516000908152600e60205260409020805460ff19166001179055600c54610b2d8533856112ab565b610b383382866113f4565b610b42818661140f565b600c54610b50906001612350565b600c5590505b9392505050565b600d546000906001600160a01b03163314610bba5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c7565b6001600160a01b038216610c1f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104c7565b600d80546001600160a01b0319166001600160a01b03841690811790915560405181907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35060015b919050565b60006106696002836114d5565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610cb382610764565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610669825490565b6000610d0182610c71565b610d625760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016104c7565b6000610d6d83610764565b9050806001600160a01b0316846001600160a01b03161480610da85750836001600160a01b0316610d9d8461045f565b6001600160a01b0316145b80610dd857506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316610df382610764565b6001600160a01b031614610e5b5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016104c7565b6001600160a01b038216610ebd5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016104c7565b610ec8600082610c7e565b6001600160a01b0383166000908152600160205260409020610eea90826114ed565b506001600160a01b0382166000908152600160205260409020610f0d90826114f9565b50610f1a60028284611505565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000610666838361151b565b610f7681610764565b6001600160a01b0316336001600160a01b031614610fc95760405162461bcd60e51b815260206004820152601060248201526f31b0b63632b9103737ba1037bbb732b960811b60448201526064016104c7565b6000610fd482610764565b9050610fe1600083610c7e565b60008281526008602052604090208054610ffa906123d6565b15905061101857600082815260086020526040812061101891611dc2565b6001600160a01b038116600090815260016020526040902061103a90836114ed565b506110466002836115af565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600080808061109286866115bb565b9097909650945050505050565b80516110b290600b906020840190611dfc565b507f5514cc7324ac64a875ba50a1849367d39c8b030fe0f563c3c7142984552bc306816040516110e291906122c3565b60405180910390a150565b6000610dd8848484611666565b611105848484610de0565b611111848484846116dd565b61092d5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016104c7565b60608161119c5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156111c657806111b081612411565b91506111bf9050600a83612368565b91506111a0565b60008167ffffffffffffffff8111156111ef57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611219576020820181803683370190505b509050600061122960018461237c565b90508593505b83156112a257611240600a8561242c565b61124b906030612350565b60f81b8282611259816123bf565b93508151811061127957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535061129b600a85612368565b935061122f565b50949350505050565b600030838584606001516040516020016112c8949392919061220a565b60405160208183030381529060405280519060200120905060018160405160200161131f91907f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b60408051601f19818403018152828252805160209182012086518783015188850151600087529386018086529290925260ff16928401929092526060830191909152608082015260a0016020604051602081039080840390855afa15801561138b573d6000803e3d6000fd5b5050604051601f190151600d546001600160a01b03908116911614905061092d5760405162461bcd60e51b815260206004820152601e60248201527f4f776e6572207369676e20766572696669636174696f6e206661696c6564000060448201526064016104c7565b6105fd838383604051806020016040528060008152506117ae565b61141882610c71565b6114795760405162461bcd60e51b815260206004820152602c60248201527f4552433732314d657461646174613a2055524920736574206f66206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016104c7565b6000828152600860209081526040909120825161149892840190611dfc565b50817f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b826040516114c991906122c3565b60405180910390a25050565b60008181526001830160205260408120541515610666565b600061066683836117c6565b600061066683836118e3565b6000610dd884846001600160a01b038516611932565b815460009082106115795760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b60648201526084016104c7565b82600001828154811061159c57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b600061066683836119e1565b81546000908190831061161b5760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604482015261647360f01b60648201526084016104c7565b600084600001848154811061164057634e487b7160e01b600052603260045260246000fd5b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816116965760405162461bcd60e51b81526004016104c791906122c3565b50846116a360018361237c565b815481106116c157634e487b7160e01b600052603260045260246000fd5b9060005260206000209060020201600101549150509392505050565b60006001600160a01b0384163b6116f657506001610dd8565b6000611777630a85bd0160e11b3388878760405160240161171a9493929190612286565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001612499603291396001600160a01b0388169190611b12565b905060008180602001905181019061178f91906120c0565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b6117b9848484611b21565b61111160008585846116dd565b600081815260018301602052604081205480156118d95760006117ea60018361237c565b85549091506000906117fe9060019061237c565b9050600086600001828154811061182557634e487b7160e01b600052603260045260246000fd5b906000526020600020015490508087600001848154811061185657634e487b7160e01b600052603260045260246000fd5b60009182526020909120015561186d836001612350565b6000828152600189016020526040902055865487908061189d57634e487b7160e01b600052603160045260246000fd5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610669565b6000915050610669565b600081815260018301602052604081205461192a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610669565b506000610669565b600082815260018401602052604081205480611997575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055610b56565b82856119a460018461237c565b815481106119c257634e487b7160e01b600052603260045260246000fd5b9060005260206000209060020201600101819055506000915050610b56565b600081815260018301602052604081205480156118d9576000611a0560018361237c565b8554909150600090611a199060019061237c565b90506000866000018281548110611a4057634e487b7160e01b600052603260045260246000fd5b9060005260206000209060020201905080876000018481548110611a7457634e487b7160e01b600052603260045260246000fd5b60009182526020909120825460029092020190815560019182015490820155611a9e908490612350565b815460009081526001890160205260409020558654879080611ad057634e487b7160e01b600052603160045260246000fd5b60008281526020808220600260001990940193840201828155600190810183905592909355888152898201909252604082209190915594506106699350505050565b6060610dd88484600085611c61565b6001600160a01b038316611b775760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016104c7565b611b8082610c71565b15611bcd5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016104c7565b6001600160a01b0383166000908152600160205260409020611bef90836114f9565b50611bfc60028385611505565b506000828152600a6020908152604080832080546001600160a01b0319163317905560099091528082208390555183916001600160a01b038616917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4505050565b606082471015611cc25760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016104c7565b843b611d105760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016104c7565b600080866001600160a01b03168587604051611d2c91906121ee565b60006040518083038185875af1925050503d8060008114611d69576040519150601f19603f3d011682016040523d82523d6000602084013e611d6e565b606091505b5091509150611d7e828286611d89565b979650505050505050565b60608315611d98575081610b56565b825115611da85782518084602001fd5b8160405162461bcd60e51b81526004016104c791906122c3565b508054611dce906123d6565b6000825580601f10611dde575050565b601f0160209004906000526020600020908101906106e89190611e80565b828054611e08906123d6565b90600052602060002090601f016020900481019282611e2a5760008555611e70565b82601f10611e4357805160ff1916838001178555611e70565b82800160010185558215611e70579182015b82811115611e70578251825591602001919060010190611e55565b50611e7c929150611e80565b5090565b5b80821115611e7c5760008155600101611e81565b600067ffffffffffffffff80841115611eb057611eb061246c565b604051601f8501601f19908116603f01168101908282118183101715611ed857611ed861246c565b81604052809350858152868686011115611ef157600080fd5b858560208301376000602087830101525050509392505050565b80356001600160a01b0381168114610c6c57600080fd5b600082601f830112611f32578081fd5b61066683833560208501611e95565b600060208284031215611f52578081fd5b61066682611f0b565b60008060408385031215611f6d578081fd5b611f7683611f0b565b9150611f8460208401611f0b565b90509250929050565b600080600060608486031215611fa1578081fd5b611faa84611f0b565b9250611fb860208501611f0b565b9150604084013590509250925092565b60008060008060808587031215611fdd578081fd5b611fe685611f0b565b9350611ff460208601611f0b565b925060408501359150606085013567ffffffffffffffff811115612016578182fd5b8501601f81018713612026578182fd5b61203587823560208401611e95565b91505092959194509250565b60008060408385031215612053578182fd5b61205c83611f0b565b915060208301358015158114612070578182fd5b809150509250929050565b6000806040838503121561208d578182fd5b61209683611f0b565b946020939093013593505050565b6000602082840312156120b5578081fd5b8135610b5681612482565b6000602082840312156120d1578081fd5b8151610b5681612482565b6000602082840312156120ed578081fd5b813567ffffffffffffffff811115612103578182fd5b610dd884828501611f22565b600080600083850360c0811215612124578384fd5b843567ffffffffffffffff81111561213a578485fd5b61214687828801611f22565b945050602085013592506080603f1982011215612161578182fd5b5061216a612327565b604085013560ff8116811461217d578283fd5b80825250606085013560208201526080850135604082015260a08501356060820152809150509250925092565b6000602082840312156121bb578081fd5b5035919050565b600081518084526121da816020860160208601612393565b601f01601f19169290920160200192915050565b60008251612200818460208701612393565b9190910192915050565b60006bffffffffffffffffffffffff19808760601b168352808660601b166014840152508351612241816028850160208801612393565b6028920191820192909252604801949350505050565b60008351612269818460208801612393565b83519083019061227d818360208801612393565b01949350505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906122b9908301846121c2565b9695505050505050565b60208152600061066660208301846121c2565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6040516080810167ffffffffffffffff8111828210171561234a5761234a61246c565b60405290565b6000821982111561236357612363612440565b500190565b60008261237757612377612456565b500490565b60008282101561238e5761238e612440565b500390565b60005b838110156123ae578181015183820152602001612396565b8381111561092d5750506000910152565b6000816123ce576123ce612440565b506000190190565b600181811c908216806123ea57607f821691505b6020821081141561240b57634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561242557612425612440565b5060010190565b60008261243b5761243b612456565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b0319811681146106e857600080fdfe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220ef9295bb260beb81fb5c7561d49ed674d939ba2c7b1d48c891125ea381a568c564736f6c6343000804003368747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066732f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953616e6453746f726d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004534d544100000000000000000000000000000000000000000000000000000000

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

00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953616e6453746f726d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004534d544100000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name (string): SandStorm
Arg [1] : symbol (string): SMTA

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000009
Arg [3] : 53616e6453746f726d0000000000000000000000000000000000000000000000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [5] : 534d544100000000000000000000000000000000000000000000000000000000


Deployed ByteCode Sourcemap

28219:2348:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13068:150;;;;;;:::i;:::-;-1:-1:-1;;;;;;13177:33:0;13153:4;13177:33;;;;;;;;;;;;;;13068:150;;;;8149:14:1;;8142:22;8124:41;;8112:2;8097:18;13068:150:0;;;;;;;;18366:100;;;:::i;:::-;;;;;;;:::i;20393:221::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;7431:32:1;;;7413:51;;7401:2;7386:18;20393:221:0;7368:102:1;19981:404:0;;;;;;:::i;:::-;;:::i;:::-;;19676:117;;;:::i;:::-;;;18313:25:1;;;18301:2;18286:18;19676:117:0;18268:76:1;21730:252:0;;;;;;:::i;:::-;;:::i;19506:162::-;;;;;;:::i;:::-;;:::i;21990:151::-;;;;;;:::i;:::-;;:::i;30426:138::-;;;;;;:::i;:::-;;:::i;19801:172::-;;;;;;:::i;:::-;;:::i;30312:102::-;;;;;;:::i;:::-;;:::i;18181:177::-;;;;;;:::i;:::-;;:::i;19146:97::-;;;:::i;17765:221::-;;;;;;:::i;:::-;;:::i;28289:20::-;;;;;-1:-1:-1;;;;;28289:20:0;;;18474:104;;;:::i;20976:295::-;;;;;;:::i;:::-;;:::i;23263:287::-;;;;;;:::i;:::-;;:::i;19251:121::-;;;;;;:::i;:::-;19317:7;19344:20;;;:11;:20;;;;;;;19251:121;18586:552;;;;;;:::i;:::-;;:::i;28255:27::-;;;;;;29828:476;;;;;;:::i;:::-;;:::i;19380:118::-;;;;;;:::i;:::-;19446:7;19473:17;;;:8;:17;;;;;;-1:-1:-1;;;;;19473:17:0;;19380:118;21558:164;;;;;;:::i;:::-;-1:-1:-1;;;;;21679:25:0;;;21655:4;21679:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;21558:164;28843:271;;;;;;:::i;:::-;;:::i;18366:100::-;18420:13;18453:5;18446:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18366:100;:::o;20393:221::-;20469:7;20497:16;20505:7;20497;:16::i;:::-;20489:73;;;;-1:-1:-1;;;20489:73:0;;14474:2:1;20489:73:0;;;14456:21:1;14513:2;14493:18;;;14486:30;14552:34;14532:18;;;14525:62;-1:-1:-1;;;14603:18:1;;;14596:42;14655:19;;20489:73:0;;;;;;;;;-1:-1:-1;20582:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;20582:24:0;;20393:221::o;19981:404::-;20062:13;20078:23;20093:7;20078:14;:23::i;:::-;20062:39;;20126:5;-1:-1:-1;;;;;20120:11:0;:2;-1:-1:-1;;;;;20120:11:0;;;20112:57;;;;-1:-1:-1;;;20112:57:0;;16841:2:1;20112:57:0;;;16823:21:1;16880:2;16860:18;;;16853:30;16919:34;16899:18;;;16892:62;-1:-1:-1;;;16970:18:1;;;16963:31;17011:19;;20112:57:0;16813:223:1;20112:57:0;15607:10;-1:-1:-1;;;;;20190:21:0;;;;:69;;-1:-1:-1;20215:44:0;20239:5;15607:10;21558:164;:::i;20215:44::-;20182:161;;;;-1:-1:-1;;;20182:161:0;;12515:2:1;20182:161:0;;;12497:21:1;12554:2;12534:18;;;12527:30;12593:34;12573:18;;;12566:62;12664:26;12644:18;;;12637:54;12708:19;;20182:161:0;12487:246:1;20182:161:0;20356:21;20365:2;20369:7;20356:8;:21::i;:::-;19981:404;;;:::o;19676:117::-;19737:7;19764:21;:12;:19;:21::i;:::-;19757:28;;19676:117;:::o;21730:252::-;21838:41;15607:10;21871:7;21838:18;:41::i;:::-;21830:103;;;;-1:-1:-1;;;21830:103:0;;;;;;;:::i;:::-;21946:28;21956:4;21962:2;21966:7;21946:9;:28::i;19506:162::-;-1:-1:-1;;;;;19630:20:0;;19603:7;19630:20;;;:13;:20;;;;;:30;;19654:5;19630:23;:30::i;:::-;19623:37;;19506:162;;;;;:::o;21990:151::-;22094:39;22111:4;22117:2;22121:7;22094:39;;;;;;;;;;;;:16;:39::i;30426:138::-;30485:16;30493:7;30485;:16::i;:::-;30477:54;;;;-1:-1:-1;;;30477:54:0;;16487:2:1;30477:54:0;;;16469:21:1;16526:2;16506:18;;;16499:30;16565:27;16545:18;;;16538:55;16610:18;;30477:54:0;16459:175:1;30477:54:0;30542:14;30548:7;30542:5;:14::i;:::-;30426:138;:::o;19801:172::-;19876:7;;19918:22;:12;19934:5;19918:15;:22::i;:::-;-1:-1:-1;19896:44:0;19801:172;-1:-1:-1;;;19801:172:0:o;30312:102::-;28759:5;;-1:-1:-1;;;;;28759:5:0;28768:10;28759:19;28751:64;;;;-1:-1:-1;;;28751:64:0;;15300:2:1;28751:64:0;;;15282:21:1;;;15319:18;;;15312:30;15378:34;15358:18;;;15351:62;15430:18;;28751:64:0;15272:182:1;28751:64:0;30385:21:::1;30397:8;30385:11;:21::i;18181:177::-:0;18253:7;18280:70;18297:7;18280:70;;;;;;;;;;;;;;;;;:12;;:70;:16;:70::i;19146:97::-;19194:13;19227:8;19220:15;;;;;:::i;17765:221::-;17837:7;-1:-1:-1;;;;;17865:19:0;;17857:74;;;;-1:-1:-1;;;17857:74:0;;12940:2:1;17857:74:0;;;12922:21:1;12979:2;12959:18;;;12952:30;13018:34;12998:18;;;12991:62;-1:-1:-1;;;13069:18:1;;;13062:40;13119:19;;17857:74:0;12912:232:1;17857:74:0;-1:-1:-1;;;;;17949:20:0;;;;;;:13;:20;;;;;:29;;:27;:29::i;18474:104::-;18530:13;18563:7;18556:14;;;;;:::i;20976:295::-;-1:-1:-1;;;;;21079:24:0;;15607:10;21079:24;;21071:62;;;;-1:-1:-1;;;21071:62:0;;11341:2:1;21071:62:0;;;11323:21:1;11380:2;11360:18;;;11353:30;11419:27;11399:18;;;11392:55;11464:18;;21071:62:0;11313:175:1;21071:62:0;15607:10;21146:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;21146:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;21146:53:0;;;;;;;;;;21215:48;;8124:41:1;;;21146:42:0;;15607:10;21215:48;;8097:18:1;21215:48:0;;;;;;;20976:295;;:::o;23263:287::-;23395:41;15607:10;23428:7;23395:18;:41::i;:::-;23387:103;;;;-1:-1:-1;;;23387:103:0;;;;;;;:::i;:::-;23501:39;23515:4;23521:2;23525:7;23534:5;23501:13;:39::i;:::-;23263:287;;;;:::o;18586:552::-;18659:13;18693:16;18701:7;18693;:16::i;:::-;18685:76;;;;-1:-1:-1;;;18685:76:0;;16071:2:1;18685:76:0;;;16053:21:1;16110:2;16090:18;;;16083:30;16149:34;16129:18;;;16122:62;-1:-1:-1;;;16200:18:1;;;16193:45;16255:19;;18685:76:0;16043:237:1;18685:76:0;18774:23;18800:19;;;:10;:19;;;;;18774:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18830:18;18851:9;:7;:9::i;:::-;18830:30;;18883:4;18877:18;18899:1;18877:23;18873:72;;;-1:-1:-1;18924:9:0;18586:552;-1:-1:-1;;18586:552:0:o;18873:72::-;18959:23;;:27;18955:108;;19034:4;19040:9;19017:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19003:48;;;;18586:552;;;:::o;18955:108::-;19104:4;19110:18;:7;:16;:18::i;:::-;19087:42;;;;;;;;;:::i;29828:476::-;29967:10;;;;29928:7;29957:21;;;:9;:21;;;;;;;;29956:22;29948:56;;;;-1:-1:-1;;;29948:56:0;;18019:2:1;29948:56:0;;;18001:21:1;18058:2;18038:18;;;18031:30;-1:-1:-1;;;18077:18:1;;;18070:51;18138:18;;29948:56:0;17991:171:1;29948:56:0;30025:10;;;;30015:21;;;;:9;:21;;;;;:28;;-1:-1:-1;;30015:28:0;30039:4;30015:28;;;30074:12;;30097:38;30108:8;30118:10;30025:4;30097:10;:38::i;:::-;30146:37;30156:10;30168:9;30179:3;30146:9;:37::i;:::-;30194:33;30207:9;30218:8;30194:12;:33::i;:::-;30253:12;;:16;;30268:1;30253:16;:::i;:::-;30238:12;:31;30287:9;-1:-1:-1;29828:476:0;;;;;;:::o;28843:271::-;28759:5;;28915:4;;-1:-1:-1;;;;;28759:5:0;28768:10;28759:19;28751:64;;;;-1:-1:-1;;;28751:64:0;;15300:2:1;28751:64:0;;;15282:21:1;;;15319:18;;;15312:30;15378:34;15358:18;;;15351:62;15430:18;;28751:64:0;15272:182:1;28751:64:0;-1:-1:-1;;;;;28939:22:0;::::1;28931:73;;;::::0;-1:-1:-1;;;28931:73:0;;9827:2:1;28931:73:0::1;::::0;::::1;9809:21:1::0;9866:2;9846:18;;;9839:30;9905:34;9885:18;;;9878:62;-1:-1:-1;;;9956:18:1;;;9949:36;10002:19;;28931:73:0::1;9799:228:1::0;28931:73:0::1;29015:5;:16:::0;;-1:-1:-1;;;;;;29015:16:0::1;-1:-1:-1::0;;;;;29015:16:0;::::1;::::0;;::::1;::::0;;;29047:37:::1;::::0;29015:16;;29047:37:::1;::::0;-1:-1:-1;;29047:37:0::1;-1:-1:-1::0;29102:4:0::1;28826:1;28843:271:::0;;;:::o;23838:127::-;23903:4;23927:30;:12;23949:7;23927:21;:30::i;27919:192::-;27994:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;27994:29:0;-1:-1:-1;;;;;27994:29:0;;;;;;;;:24;;28048:23;27994:24;28048:14;:23::i;:::-;-1:-1:-1;;;;;28039:46:0;;;;;;;;;;;27919:192;;:::o;4097:123::-;4166:7;4193:19;4201:3;2250:19;;2167:110;23973:355;24066:4;24091:16;24099:7;24091;:16::i;:::-;24083:73;;;;-1:-1:-1;;;24083:73:0;;12102:2:1;24083:73:0;;;12084:21:1;12141:2;12121:18;;;12114:30;12180:34;12160:18;;;12153:62;-1:-1:-1;;;12231:18:1;;;12224:42;12283:19;;24083:73:0;12074:234:1;24083:73:0;24167:13;24183:23;24198:7;24183:14;:23::i;:::-;24167:39;;24236:5;-1:-1:-1;;;;;24225:16:0;:7;-1:-1:-1;;;;;24225:16:0;;:51;;;;24269:7;-1:-1:-1;;;;;24245:31:0;:20;24257:7;24245:11;:20::i;:::-;-1:-1:-1;;;;;24245:31:0;;24225:51;:94;;;-1:-1:-1;;;;;;21679:25:0;;;21655:4;21679:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;24280:39;24217:103;23973:355;-1:-1:-1;;;;23973:355:0:o;26095:547::-;26220:4;-1:-1:-1;;;;;26193:31:0;:23;26208:7;26193:14;:23::i;:::-;-1:-1:-1;;;;;26193:31:0;;26185:85;;;;-1:-1:-1;;;26185:85:0;;15661:2:1;26185:85:0;;;15643:21:1;15700:2;15680:18;;;15673:30;15739:34;15719:18;;;15712:62;-1:-1:-1;;;15790:18:1;;;15783:39;15839:19;;26185:85:0;15633:231:1;26185:85:0;-1:-1:-1;;;;;26307:16:0;;26299:65;;;;-1:-1:-1;;;26299:65:0;;10936:2:1;26299:65:0;;;10918:21:1;10975:2;10955:18;;;10948:30;11014:34;10994:18;;;10987:62;-1:-1:-1;;;11065:18:1;;;11058:34;11109:19;;26299:65:0;10908:226:1;26299:65:0;26429:29;26446:1;26450:7;26429:8;:29::i;:::-;-1:-1:-1;;;;;26471:19:0;;;;;;:13;:19;;;;;:35;;26498:7;26471:26;:35::i;:::-;-1:-1:-1;;;;;;26517:17:0;;;;;;:13;:17;;;;;:30;;26539:7;26517:21;:30::i;:::-;-1:-1:-1;26560:29:0;:12;26577:7;26586:2;26560:16;:29::i;:::-;;26626:7;26622:2;-1:-1:-1;;;;;26607:27:0;26616:4;-1:-1:-1;;;;;26607:27:0;;;;;;;;;;;26095:547;;;:::o;8895:137::-;8966:7;9001:22;9005:3;9017:5;9001:3;:22::i;25537:550::-;25619:16;25627:7;25619;:16::i;:::-;-1:-1:-1;;;;;25605:30:0;:10;-1:-1:-1;;;;;25605:30:0;;25597:58;;;;-1:-1:-1;;;25597:58:0;;10591:2:1;25597:58:0;;;10573:21:1;10630:2;10610:18;;;10603:30;-1:-1:-1;;;10649:18:1;;;10642:46;10705:18;;25597:58:0;10563:166:1;25597:58:0;25666:13;25682:23;25697:7;25682:14;:23::i;:::-;25666:39;;25797:29;25814:1;25818:7;25797:8;:29::i;:::-;25849:19;;;;:10;:19;;;;;25843:33;;;;;:::i;:::-;:38;;-1:-1:-1;25839:97:0;;25905:19;;;;:10;:19;;;;;25898:26;;;:::i;:::-;-1:-1:-1;;;;;25948:20:0;;;;;;:13;:20;;;;;:36;;25976:7;25948:27;:36::i;:::-;-1:-1:-1;25997:28:0;:12;26017:7;25997:19;:28::i;:::-;-1:-1:-1;26043:36:0;;26071:7;;26067:1;;-1:-1:-1;;;;;26043:36:0;;;;;26067:1;;26043:36;25537:550;;:::o;4228:236::-;4308:7;;;;4368:22;4372:3;4384:5;4368:3;:22::i;:::-;4337:53;;;;-1:-1:-1;4228:236:0;-1:-1:-1;;;;;4228:236:0:o;27161:138::-;27234:19;;;;:8;;:19;;;;;:::i;:::-;;27269:22;27282:8;27269:22;;;;;;:::i;:::-;;;;;;;;27161:138;:::o;4901:213::-;5008:7;5059:44;5064:3;5084;5090:12;5059:4;:44::i;23558:272::-;23672:28;23682:4;23688:2;23692:7;23672:9;:28::i;:::-;23719:48;23742:4;23748:2;23752:7;23761:5;23719:22;:48::i;:::-;23711:111;;;;-1:-1:-1;;;23711:111:0;;9408:2:1;23711:111:0;;;9390:21:1;9447:2;9427:18;;;9420:30;9486:34;9466:18;;;9459:62;-1:-1:-1;;;9537:18:1;;;9530:48;9595:19;;23711:111:0;9380:240:1;91:557:0;147:13;179:10;175:53;;-1:-1:-1;;206:10:0;;;;;;;;;;;;-1:-1:-1;;;206:10:0;;;;;91:557::o;175:53::-;253:5;238:12;294:78;301:9;;294:78;;327:8;;;;:::i;:::-;;-1:-1:-1;350:10:0;;-1:-1:-1;358:2:0;350:10;;:::i;:::-;;;294:78;;;382:19;414:6;404:17;;;;;;-1:-1:-1;;;404:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;404:17:0;-1:-1:-1;382:39:0;-1:-1:-1;432:13:0;448:10;457:1;448:6;:10;:::i;:::-;432:26;;476:5;469:12;;492:117;499:9;;492:117;;561:9;568:2;561:4;:9;:::i;:::-;556:14;;:2;:14;:::i;:::-;543:29;;525:6;532:7;;;;:::i;:::-;;;525:15;;;;;;-1:-1:-1;;;525:15:0;;;;;;;;;;;;:47;-1:-1:-1;;;;;525:47:0;;;;;;;;-1:-1:-1;587:10:0;595:2;587:10;;:::i;:::-;;;492:117;;;-1:-1:-1;633:6:0;91:557;-1:-1:-1;;;;91:557:0:o;29122:356::-;29225:12;29267:4;29273:6;29281:8;29291:4;:10;;;29250:52;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;29240:63;;;;;;29225:78;;29331:104;29404:4;29351:58;;;;;;;7124:66:1;7112:79;;7216:2;7207:12;;7200:28;;;;7253:2;7244:12;;7102:160;29351:58:0;;;;-1:-1:-1;;29351:58:0;;;;;;;;;29341:69;;29351:58;29341:69;;;;29412:6;;29420;;;;29428;;;;29412;29331:104;;;;;;;;8403:25:1;;;;8476:4;8464:17;8444:18;;;8437:45;;;;8498:18;;;8491:34;;;;8541:18;;;8534:34;8375:19;;29331:104:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;29331:104:0;;-1:-1:-1;;29331:104:0;;29322:5;;-1:-1:-1;;;;;29322:5:0;;;:113;;;;-1:-1:-1;29314:156:0;;;;-1:-1:-1;;;29314:156:0;;13351:2:1;29314:156:0;;;13333:21:1;13390:2;13370:18;;;13363:30;13429:32;13409:18;;;13402:60;13479:18;;29314:156:0;13323:180:1;24336:128:0;24425:31;24435:2;24439:7;24448:3;24425:31;;;;;;;;;;;;:9;:31::i;26898:255::-;26998:16;27006:7;26998;:16::i;:::-;26990:73;;;;-1:-1:-1;;;26990:73:0;;14887:2:1;26990:73:0;;;14869:21:1;14926:2;14906:18;;;14899:30;14965:34;14945:18;;;14938:62;-1:-1:-1;;;15016:18:1;;;15009:42;15068:19;;26990:73:0;14859:234:1;26990:73:0;27074:19;;;;:10;:19;;;;;;;;:31;;;;;;;;:::i;:::-;;27137:7;27122:23;27126:9;27122:23;;;;;;:::i;:::-;;;;;;;;26898:255;;:::o;3938:151::-;4022:4;2129:17;;;:12;;;:17;;;;;;:22;;4046:35;2034:125;8474:137;8544:4;8568:35;8576:3;8596:5;8568:7;:35::i;8335:131::-;8402:4;8426:32;8431:3;8451:5;8426:4;:32::i;3595:185::-;3684:4;3708:64;3713:3;3733;-1:-1:-1;;;;;3747:23:0;;3708:4;:64::i;6485:204::-;6580:18;;6552:7;;6580:26;-1:-1:-1;6572:73:0;;;;-1:-1:-1;;;6572:73:0;;9005:2:1;6572:73:0;;;8987:21:1;9044:2;9024:18;;;9017:30;9083:34;9063:18;;;9056:62;-1:-1:-1;;;9134:18:1;;;9127:32;9176:19;;6572:73:0;8977:224:1;6572:73:0;6663:3;:11;;6675:5;6663:18;;;;;;-1:-1:-1;;;6663:18:0;;;;;;;;;;;;;;;;;6656:25;;6485:204;;;;:::o;3788:142::-;3865:4;3889:33;3897:3;3917;3889:7;:33::i;2285:279::-;2389:19;;2352:7;;;;2389:27;-1:-1:-1;2381:74:0;;;;-1:-1:-1;;;2381:74:0;;13710:2:1;2381:74:0;;;13692:21:1;13749:2;13729:18;;;13722:30;13788:34;13768:18;;;13761:62;-1:-1:-1;;;13839:18:1;;;13832:32;13881:19;;2381:74:0;13682:224:1;2381:74:0;2468:22;2493:3;:12;;2506:5;2493:19;;;;;;-1:-1:-1;;;2493:19:0;;;;;;;;;;;;;;;;;;;2468:44;;2531:5;:10;;;2543:5;:12;;;2523:33;;;;;2285:279;;;;;:::o;3207:319::-;3301:7;3340:17;;;:12;;;:17;;;;;;3391:12;3376:13;3368:36;;;;-1:-1:-1;;;3368:36:0;;;;;;;;:::i;:::-;-1:-1:-1;3458:3:0;3471:12;3482:1;3471:8;:12;:::i;:::-;3458:26;;;;;;-1:-1:-1;;;3458:26:0;;;;;;;;;;;;;;;;;;;:33;;;3451:40;;;3207:319;;;;;:::o;27307:604::-;27428:4;-1:-1:-1;;;;;27455:13:0;;9183:20;27450:60;;-1:-1:-1;27494:4:0;27487:11;;27450:60;27520:23;27546:252;-1:-1:-1;;;15607:10:0;27686:4;27705:7;27727:5;27562:181;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;27562:181:0;;;;;;;-1:-1:-1;;;;;27562:181:0;;;;;;;;;;;27546:252;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;27546:15:0;;;:252;:15;:252::i;:::-;27520:278;;27809:13;27836:10;27825:32;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;27876:26:0;-1:-1:-1;;;27876:26:0;;-1:-1:-1;;;27307:604:0;;;;;;:::o;24472:268::-;24581:23;24587:2;24591:7;24600:3;24581:5;:23::i;:::-;24623:54;24654:1;24658:2;24662:7;24671:5;24623:22;:54::i;5552:671::-;5618:4;5656:19;;;:12;;;:19;;;;;;5692:15;;5688:528;;5762:21;5786:14;5799:1;5786:10;:14;:::i;:::-;5835:18;;5762:38;;-1:-1:-1;5815:17:0;;5835:22;;5856:1;;5835:22;:::i;:::-;5815:42;;5872:17;5892:3;:11;;5904:9;5892:22;;;;;;-1:-1:-1;;;5892:22:0;;;;;;;;;;;;;;;;;5872:42;;5960:9;5931:3;:11;;5943:13;5931:26;;;;;;-1:-1:-1;;;5931:26:0;;;;;;;;;;;;;;;;;;:38;6010:17;:13;6026:1;6010:17;:::i;:::-;5984:23;;;;:12;;;:23;;;;;:43;6071:17;;5984:3;;6071:17;;;-1:-1:-1;;;6071:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;6112:3;:12;;:19;6125:5;6112:19;;;;;;;;;;;6105:26;;;6155:4;6148:11;;;;;;;;5688:528;6199:5;6192:12;;;;;5253:291;5316:4;2129:17;;;:12;;;:17;;;;;;5333:204;;-1:-1:-1;5376:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;5436:18;;5414:19;;;:12;;;:19;;;;;;:40;;;;5469:11;;5333:204;-1:-1:-1;5520:5:0;5513:12;;873:470;949:4;985:17;;;:12;;;:17;;;;;;1019:13;1015:321;;-1:-1:-1;;1104:38:0;;;;;;;;;;;;;;;;;;1086:57;;;;;;;;:12;:57;;;;;;;;;;;;;;;;;;;;;;;;1178:19;;1158:17;;;:12;;;:17;;;;;;;:39;1212:11;;1015:321;1292:5;1256:3;1269:12;1280:1;1269:8;:12;:::i;:::-;1256:26;;;;;;-1:-1:-1;;;1256:26:0;;;;;;;;;;;;;;;;;;;:33;;:41;;;;1319:5;1312:12;;;;;1351:675;1415:4;1451:17;;;:12;;;:17;;;;;;1485:13;;1481:538;;1551:21;1575:12;1586:1;1575:8;:12;:::i;:::-;1622:19;;1551:36;;-1:-1:-1;1602:17:0;;1622:23;;1644:1;;1622:23;:::i;:::-;1602:43;;1660:26;1689:3;:12;;1702:9;1689:23;;;;;;-1:-1:-1;;;1689:23:0;;;;;;;;;;;;;;;;;;;1660:52;;1759:9;1729:3;:12;;1742:13;1729:27;;;;;;-1:-1:-1;;;1729:27:0;;;;;;;;;;;;;;;;;:39;;:27;;;;;:39;;;;;;;;;;;;1814:17;;:13;;:17;:::i;:::-;1796:14;;1783:28;;;;:12;;;:28;;;;;:48;1875:18;;1783:3;;1875:18;;;-1:-1:-1;;;1875:18:0;;;;;;;;;;;;;;;;;;-1:-1:-1;;1875:18:0;;;;;;;;;;;;;;;;;;;;;1917:17;;;:12;;;:17;;;;;;1910:24;;;;1875:18;-1:-1:-1;1951:11:0;;-1:-1:-1;;;;1951:11:0;9754:195;9857:12;9889:52;9911:6;9919:4;9925:1;9928:12;9889:21;:52::i;24748:504::-;-1:-1:-1;;;;;24841:16:0;;24833:61;;;;-1:-1:-1;;;24833:61:0;;14113:2:1;24833:61:0;;;14095:21:1;;;14132:18;;;14125:30;14191:34;14171:18;;;14164:62;14243:18;;24833:61:0;14085:182:1;24833:61:0;24914:16;24922:7;24914;:16::i;:::-;24913:17;24905:58;;;;-1:-1:-1;;;24905:58:0;;10234:2:1;24905:58:0;;;10216:21:1;10273:2;10253:18;;;10246:30;10312;10292:18;;;10285:58;10360:18;;24905:58:0;10206:178:1;24905:58:0;-1:-1:-1;;;;;25034:17:0;;;;;;:13;:17;;;;;:30;;25056:7;25034:21;:30::i;:::-;-1:-1:-1;25077:29:0;:12;25094:7;25103:2;25077:16;:29::i;:::-;-1:-1:-1;25117:17:0;;;;:8;:17;;;;;;;;:30;;-1:-1:-1;;;;;;25117:30:0;25137:10;25117:30;;;25158:11;:20;;;;;;:26;;;25202:33;25126:7;;-1:-1:-1;;;;;25202:33:0;;;;;25117:17;;25202:33;24748:504;;;:::o;10191:470::-;10318:12;10376:5;10351:21;:30;;10343:81;;;;-1:-1:-1;;;10343:81:0;;11695:2:1;10343:81:0;;;11677:21:1;11734:2;11714:18;;;11707:30;11773:34;11753:18;;;11746:62;-1:-1:-1;;;11824:18:1;;;11817:36;11870:19;;10343:81:0;11667:228:1;10343:81:0;9183:20;;10435:60;;;;-1:-1:-1;;;10435:60:0;;17661:2:1;10435:60:0;;;17643:21:1;17700:2;17680:18;;;17673:30;17739:31;17719:18;;;17712:59;17788:18;;10435:60:0;17633:179:1;10435:60:0;10509:12;10523:23;10550:6;-1:-1:-1;;;;;10550:11:0;10570:5;10578:4;10550:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10508:75;;;;10601:52;10619:7;10628:10;10640:12;10601:17;:52::i;:::-;10594:59;10191:470;-1:-1:-1;;;;;;;10191:470:0:o;11825:515::-;11940:12;11969:7;11965:368;;;-1:-1:-1;12000:10:0;11993:17;;11965:368;12047:17;;:21;12043:279;;12150:10;12144:17;12211:15;12198:10;12194:2;12190:19;12183:44;12098:148;12293:12;12286:20;;-1:-1:-1;;;12286:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:631:1;78:5;108:18;149:2;141:6;138:14;135:2;;;155:18;;:::i;:::-;230:2;224:9;198:2;284:15;;-1:-1:-1;;280:24:1;;;306:2;276:33;272:42;260:55;;;330:18;;;350:22;;;327:46;324:2;;;376:18;;:::i;:::-;416:10;412:2;405:22;445:6;436:15;;475:6;467;460:22;515:3;506:6;501:3;497:16;494:25;491:2;;;532:1;529;522:12;491:2;582:6;577:3;570:4;562:6;558:17;545:44;637:1;630:4;621:6;613;609:19;605:30;598:41;;;;88:557;;;;;:::o;650:173::-;718:20;;-1:-1:-1;;;;;767:31:1;;757:42;;747:2;;813:1;810;803:12;828:229;871:5;924:3;917:4;909:6;905:17;901:27;891:2;;946:5;939;932:20;891:2;972:79;1047:3;1038:6;1025:20;1018:4;1010:6;1006:17;972:79;:::i;1062:196::-;1121:6;1174:2;1162:9;1153:7;1149:23;1145:32;1142:2;;;1195:6;1187;1180:22;1142:2;1223:29;1242:9;1223:29;:::i;1263:270::-;1331:6;1339;1392:2;1380:9;1371:7;1367:23;1363:32;1360:2;;;1413:6;1405;1398:22;1360:2;1441:29;1460:9;1441:29;:::i;:::-;1431:39;;1489:38;1523:2;1512:9;1508:18;1489:38;:::i;:::-;1479:48;;1350:183;;;;;:::o;1538:338::-;1615:6;1623;1631;1684:2;1672:9;1663:7;1659:23;1655:32;1652:2;;;1705:6;1697;1690:22;1652:2;1733:29;1752:9;1733:29;:::i;:::-;1723:39;;1781:38;1815:2;1804:9;1800:18;1781:38;:::i;:::-;1771:48;;1866:2;1855:9;1851:18;1838:32;1828:42;;1642:234;;;;;:::o;1881:696::-;1976:6;1984;1992;2000;2053:3;2041:9;2032:7;2028:23;2024:33;2021:2;;;2075:6;2067;2060:22;2021:2;2103:29;2122:9;2103:29;:::i;:::-;2093:39;;2151:38;2185:2;2174:9;2170:18;2151:38;:::i;:::-;2141:48;;2236:2;2225:9;2221:18;2208:32;2198:42;;2291:2;2280:9;2276:18;2263:32;2318:18;2310:6;2307:30;2304:2;;;2355:6;2347;2340:22;2304:2;2383:22;;2436:4;2428:13;;2424:27;-1:-1:-1;2414:2:1;;2470:6;2462;2455:22;2414:2;2498:73;2563:7;2558:2;2545:16;2540:2;2536;2532:11;2498:73;:::i;:::-;2488:83;;;2011:566;;;;;;;:::o;2582:367::-;2647:6;2655;2708:2;2696:9;2687:7;2683:23;2679:32;2676:2;;;2729:6;2721;2714:22;2676:2;2757:29;2776:9;2757:29;:::i;:::-;2747:39;;2836:2;2825:9;2821:18;2808:32;2883:5;2876:13;2869:21;2862:5;2859:32;2849:2;;2910:6;2902;2895:22;2849:2;2938:5;2928:15;;;2666:283;;;;;:::o;2954:264::-;3022:6;3030;3083:2;3071:9;3062:7;3058:23;3054:32;3051:2;;;3104:6;3096;3089:22;3051:2;3132:29;3151:9;3132:29;:::i;:::-;3122:39;3208:2;3193:18;;;;3180:32;;-1:-1:-1;;;3041:177:1:o;3223:255::-;3281:6;3334:2;3322:9;3313:7;3309:23;3305:32;3302:2;;;3355:6;3347;3340:22;3302:2;3399:9;3386:23;3418:30;3442:5;3418:30;:::i;3483:259::-;3552:6;3605:2;3593:9;3584:7;3580:23;3576:32;3573:2;;;3626:6;3618;3611:22;3573:2;3663:9;3657:16;3682:30;3706:5;3682:30;:::i;3747:342::-;3816:6;3869:2;3857:9;3848:7;3844:23;3840:32;3837:2;;;3890:6;3882;3875:22;3837:2;3935:9;3922:23;3968:18;3960:6;3957:30;3954:2;;;4005:6;3997;3990:22;3954:2;4033:50;4075:7;4066:6;4055:9;4051:22;4033:50;:::i;4094:963::-;4203:6;4211;4219;4263:9;4254:7;4250:23;4293:3;4289:2;4285:12;4282:2;;;4315:6;4307;4300:22;4282:2;4360:9;4347:23;4393:18;4385:6;4382:30;4379:2;;;4430:6;4422;4415:22;4379:2;4458:50;4500:7;4491:6;4480:9;4476:22;4458:50;:::i;:::-;4448:60;-1:-1:-1;;4555:2:1;4540:18;;4527:32;;-1:-1:-1;4593:4:1;-1:-1:-1;;4575:16:1;;4571:27;4568:2;;;4616:6;4608;4601:22;4568:2;;4647:17;;:::i;:::-;4716:2;4705:9;4701:18;4688:32;4764:4;4755:7;4751:18;4742:7;4739:31;4729:2;;4789:6;4781;4774:22;4729:2;4821:7;4814:5;4807:22;;4889:2;4878:9;4874:18;4861:32;4856:2;4849:5;4845:14;4838:56;4954:4;4943:9;4939:20;4926:34;4921:2;4914:5;4910:14;4903:58;5021:3;5010:9;5006:19;4993:33;4988:2;4981:5;4977:14;4970:57;5046:5;5036:15;;;4230:827;;;;;:::o;5062:190::-;5121:6;5174:2;5162:9;5153:7;5149:23;5145:32;5142:2;;;5195:6;5187;5180:22;5142:2;-1:-1:-1;5223:23:1;;5132:120;-1:-1:-1;5132:120:1:o;5257:257::-;5298:3;5336:5;5330:12;5363:6;5358:3;5351:19;5379:63;5435:6;5428:4;5423:3;5419:14;5412:4;5405:5;5401:16;5379:63;:::i;:::-;5496:2;5475:15;-1:-1:-1;;5471:29:1;5462:39;;;;5503:4;5458:50;;5306:208;-1:-1:-1;;5306:208:1:o;5519:274::-;5648:3;5686:6;5680:13;5702:53;5748:6;5743:3;5736:4;5728:6;5724:17;5702:53;:::i;:::-;5771:16;;;;;5656:137;-1:-1:-1;;5656:137:1:o;5798:604::-;6031:3;6063:26;6059:31;6132:2;6123:6;6119:2;6115:15;6111:24;6106:3;6099:37;6187:2;6178:6;6174:2;6170:15;6166:24;6161:2;6156:3;6152:12;6145:46;;6220:6;6214:13;6236:62;6291:6;6286:2;6281:3;6277:12;6270:4;6262:6;6258:17;6236:62;:::i;:::-;6357:2;6317:16;;6349:11;;;6342:27;;;;6393:2;6385:11;;6039:363;-1:-1:-1;;;;6039:363:1:o;6407:470::-;6586:3;6624:6;6618:13;6640:53;6686:6;6681:3;6674:4;6666:6;6662:17;6640:53;:::i;:::-;6756:13;;6715:16;;;;6778:57;6756:13;6715:16;6812:4;6800:17;;6778:57;:::i;:::-;6851:20;;6594:283;-1:-1:-1;;;;6594:283:1:o;7475:504::-;-1:-1:-1;;;;;7760:15:1;;;7742:34;;7812:15;;7807:2;7792:18;;7785:43;7859:2;7844:18;;7837:34;;;7907:3;7902:2;7887:18;;7880:31;;;7685:4;;7928:45;;7953:19;;7945:6;7928:45;:::i;:::-;7920:53;7694:285;-1:-1:-1;;;;;;7694:285:1:o;8579:219::-;8728:2;8717:9;8710:21;8691:4;8748:44;8788:2;8777:9;8773:18;8765:6;8748:44;:::i;17041:413::-;17243:2;17225:21;;;17282:2;17262:18;;;17255:30;17321:34;17316:2;17301:18;;17294:62;-1:-1:-1;;;17387:2:1;17372:18;;17365:47;17444:3;17429:19;;17215:239::o;18349:248::-;18416:2;18410:9;18458:4;18446:17;;18493:18;18478:34;;18514:22;;;18475:62;18472:2;;;18540:18;;:::i;:::-;18576:2;18569:22;18390:207;:::o;18602:128::-;18642:3;18673:1;18669:6;18666:1;18663:13;18660:2;;;18679:18;;:::i;:::-;-1:-1:-1;18715:9:1;;18650:80::o;18735:120::-;18775:1;18801;18791:2;;18806:18;;:::i;:::-;-1:-1:-1;18840:9:1;;18781:74::o;18860:125::-;18900:4;18928:1;18925;18922:8;18919:2;;;18933:18;;:::i;:::-;-1:-1:-1;18970:9:1;;18909:76::o;18990:258::-;19062:1;19072:113;19086:6;19083:1;19080:13;19072:113;;;19162:11;;;19156:18;19143:11;;;19136:39;19108:2;19101:10;19072:113;;;19203:6;19200:1;19197:13;19194:2;;;-1:-1:-1;;19238:1:1;19220:16;;19213:27;19043:205::o;19253:136::-;19292:3;19320:5;19310:2;;19329:18;;:::i;:::-;-1:-1:-1;;;19365:18:1;;19300:89::o;19394:380::-;19473:1;19469:12;;;;19516;;;19537:2;;19591:4;19583:6;19579:17;19569:27;;19537:2;19644;19636:6;19633:14;19613:18;19610:38;19607:2;;;19690:10;19685:3;19681:20;19678:1;19671:31;19725:4;19722:1;19715:15;19753:4;19750:1;19743:15;19607:2;;19449:325;;;:::o;19779:135::-;19818:3;-1:-1:-1;;19839:17:1;;19836:2;;;19859:18;;:::i;:::-;-1:-1:-1;19906:1:1;19895:13;;19826:88::o;19919:112::-;19951:1;19977;19967:2;;19982:18;;:::i;:::-;-1:-1:-1;20016:9:1;;19957:74::o;20036:127::-;20097:10;20092:3;20088:20;20085:1;20078:31;20128:4;20125:1;20118:15;20152:4;20149:1;20142:15;20168:127;20229:10;20224:3;20220:20;20217:1;20210:31;20260:4;20257:1;20250:15;20284:4;20281:1;20274:15;20300:127;20361:10;20356:3;20352:20;20349:1;20342:31;20392:4;20389:1;20382:15;20416:4;20413:1;20406:15;20432:131;-1:-1:-1;;;;;;20506:32:1;;20496:43;;20486:2;;20553:1;20550;20543:12

Swarm Source

ipfs://ef9295bb260beb81fb5c7561d49ed674d939ba2c7b1d48c891125ea381a568c5
Loading