ETH Price: $3,422.74 (+1.94%)

Token

Crayon Codes v1 (CRAYON)
 

Overview

Max Total Supply

296 CRAYON

Holders

103

Total Transfers

-

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
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:
CrayonCodes

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 1 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-11-16
*/

// File: @openzeppelin/contracts/utils/Strings.sol



pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

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

// File: @openzeppelin/contracts/utils/Context.sol



pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/contracts/access/Ownable.sol



pragma solidity ^0.8.0;


/**
 * @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() {
        _setOwner(_msgSender());
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(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");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: @openzeppelin/contracts/utils/Address.sol



pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol



pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol



pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/interfaces/IERC165.sol



pragma solidity ^0.8.0;


// File: @openzeppelin/contracts/interfaces/IERC2981.sol



pragma solidity ^0.8.0;


/**
 * @dev Interface for the NFT Royalty Standard
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Called with the sale price to determine how much royalty is owed and to whom.
     * @param tokenId - the NFT asset queried for royalty information
     * @param salePrice - the sale price of the NFT asset specified by `tokenId`
     * @return receiver - address of who should be sent the royalty payment
     * @return royaltyAmount - the royalty payment amount for `salePrice`
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol



pragma solidity ^0.8.0;


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

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol



pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

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

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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol



pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol



pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

// File: @openzeppelin/contracts/token/ERC721/ERC721.sol



pragma solidity ^0.8.0;








/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

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

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

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

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

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

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

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

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    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);
    }

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    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");
    }

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

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    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 || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

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

        _balances[to] += 1;
        _owners[tokenId] = to;

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

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

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

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

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

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

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

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

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol



pragma solidity ^0.8.0;



/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

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

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

// File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol



pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

        return (signer, RecoverError.NoError);
    }

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

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

    /**
     * @dev Returns an Ethereum Signed 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: contracts/crayonCodes.sol


pragma solidity 0.8.10;






contract Authorizable is Ownable {
    address public trustee;

    constructor() {
        trustee = address(0x0);
    }

    modifier onlyAuthorized() {
        require(msg.sender == trustee || msg.sender == owner());
        _;
    }

    function setTrustee(address newTrustee_) external onlyOwner {
        trustee = newTrustee_;

        emit TrusteeChanged(newTrustee_);
    }

    event TrusteeChanged(address newTrustee);
}

contract CrayonCodes is ERC721Enumerable, Authorizable, IERC2981 {
    using Strings for uint256;

    address public royaltyPayoutAddress;
    bool public isMintable = true;

    struct Token {
        uint32 artistID;
        uint32 crayonID;
        uint32 editionNumber;
        uint32 royaltyAggBPS;
        address artist;
        string ipfsCID;
    }

    mapping(uint256 => Token) public tokens; // tokenID => Token
    mapping(uint256 => uint256[]) public tokensByCrayonID; // crayonID => tokenID
    mapping(uint256 => uint256[]) public tokensByArtistID; // artistID => tokenID

    string private _contractURI;
    string public tokenBaseURI;

    constructor(
        string memory title_,
        string memory symbol_,
        string memory contractURI_,
        string memory tokenBaseURI_,
        address royaltyPayoutAddress_
    ) ERC721(title_, symbol_) {
        require(royaltyPayoutAddress_ != address(0), "invalid payout address");
        _contractURI = contractURI_;
        tokenBaseURI = tokenBaseURI_;
        royaltyPayoutAddress = royaltyPayoutAddress_;
    }

    /// @notice isValidRequest validates a message by ecrecover to ensure
    //          it is signed by either the contract owner or a trustee
    //          who is set by the contract owner.
    /// @param message_ - the raw message for signing
    /// @param r_ - part of signature for validating parameters integrity
    /// @param s_ - part of signature for validating parameters integrity
    /// @param v_ - part of signature for validating parameters integrity
    function isValidRequest(
        bytes32 message_,
        bytes32 r_,
        bytes32 s_,
        uint8 v_
    ) internal view returns (bool authorized) {
        address signer = ECDSA.recover(
            ECDSA.toEthSignedMessageHash(message_),
            v_,
            r_,
            s_
        );
        authorized = signer == trustee || signer == owner();
    }

    /// @notice Call to update the minting status
    function setMintable(bool isMintable_) external onlyAuthorized {
        isMintable = isMintable_;
    }

    /// @notice Call to update the royaltyPayoutAddress
    function setRoyaltyPayoutAddress(address payoutAddress_)
        external
        onlyAuthorized
    {
        require(payoutAddress_ != address(0), "invalid payout address");
        royaltyPayoutAddress = payoutAddress_;
    }

    /// @notice Called with a valid signatures and parameters to mint a new
    //          token. The signature is to ensure the request is authorized.
    /// @param r_ - part of signature for validating parameters integrity
    /// @param s_ - part of signature for validating parameters integrity
    /// @param v_ - part of signature for validating parameters integrity
    /// @param userID_ - the user id of the NFT asset
    /// @param crayonID_ - the visual id of the NFT asset
    /// @param editionNumber_ - the edition number of the NFT asset
    /// @param royaltyAggBPS_ - the aggregated BPS for the royalty payment of the NFT asset
    /// @param ipfsCid_ - the ipfs cid of a token
    function authorizedMint(
        bytes32 r_,
        bytes32 s_,
        uint8 v_,
        uint32 userID_,
        uint32 crayonID_,
        uint32 editionNumber_,
        uint32 royaltyAggBPS_,
        address artist_,
        string calldata ipfsCid_
    ) external {
        require(isMintable, "minting process is forbidden");

        bytes32 requestHash = keccak256(
            abi.encode(
                msg.sender,
                userID_,
                crayonID_,
                editionNumber_,
                royaltyAggBPS_,
                artist_,
                ipfsCid_
            )
        );

        require(
            isValidRequest(requestHash, r_, s_, v_),
            "the minting request is not authorized"
        );

        uint256 tokenID = uint256(crayonID_) *
            100_000 +
            uint256(editionNumber_);

        Token memory token = Token(
            userID_,
            crayonID_,
            editionNumber_,
            royaltyAggBPS_,
            artist_,
            ipfsCid_
        );
        
        tokensByArtistID[userID_].push(tokenID);
        tokensByCrayonID[crayonID_].push(tokenID);
        tokens[tokenID] = token;

        _safeMint(artist_, tokenID);
        _safeTransfer(artist_, msg.sender, tokenID, "");
    }
    
    
    /// @notice Get the artist address of the given token
    /// @param tokenId_ - queried tokenId
    /// @return artist - artist of the token
    function artistOf(uint256 tokenId_)
        external
        view
        returns (address artist)
    {
         require(
            _exists(tokenId_),
            "Token not found"
        );
        artist = tokens[tokenId_].artist;
    }
    
    /// @notice Get the artist address of the given token
    /// @param crayonId_ - queried crayonId_
    /// @return tokenIds - list of tokens of this crayon
    function getTokensByCrayonID(uint256 crayonId_)
        external
        view
        returns (uint256 [] memory tokenIds)
    {
        tokenIds = tokensByCrayonID[crayonId_];
    }
    
    /// @notice Get the artist address of the given token
    /// @param artistID_ - queried userId_
    /// @return tokenIds - list of tokens of this crayon
    function getTokensByArtistID(uint256 artistID_)
        external
        view
        returns (uint256 [] memory tokenIds)
    {
        tokenIds = tokensByArtistID[artistID_];
    }
    
    /// @notice Burn given token
    /// @param tokenId_ - queried tokenId_
    function burn(uint256 tokenId_)
    external
      {
        require(_isApprovedOrOwner(msg.sender, tokenId_), "Not authorized");
        _burn(tokenId_);
      }
    

    /// @notice Called with the sale price to determine how much royalty
    //          is owed and to whom.
    /// @param tokenId_ - the NFT asset queried for royalty information
    /// @param salePrice_ - the sale price of the NFT asset specified by tokenId_
    /// @return receiver - address of who should be sent the royalty payment
    /// @return royaltyAmount - the royalty payment amount for salePrice_
    function royaltyInfo(uint256 tokenId_, uint256 salePrice_)
        external
        view
        override
        returns (address receiver, uint256 royaltyAmount)
    {
        require(
            _exists(tokenId_),
            "IERC2981: royalty info query for nonexistent token"
        );
        Token memory token = tokens[tokenId_];

        receiver = royaltyPayoutAddress;
        royaltyAmount =
            (salePrice_ * uint256(token.royaltyAggBPS)) / 100_00;
    }


    /// @notice Update the base token uri
    /// @param baseURI_ - the base tokne uri
    function setTokenBaseURI(string memory baseURI_) external onlyAuthorized {
        tokenBaseURI = baseURI_;
    }
    
    function _baseURI() internal view virtual override returns (string memory) {
        return tokenBaseURI;
    }
    
    /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
    function tokenURI(uint256 tokenId_)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId_),
            "ERC721Metadata: URI query for nonexistent token"
        );

        string memory ipfsID = tokens[tokenId_].ipfsCID;

        return string(abi.encodePacked(_baseURI(), ipfsID));
    }

    /// @notice Update the contract URI
    function setContractURI(string memory contractURI_)
        external
        onlyAuthorized
    {
        _contractURI = contractURI_;
    }

    /// @notice A URL for the opensea storefront-level metadata
    function contractURI() external view returns (string memory) {
        return _contractURI;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"title_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"string","name":"contractURI_","type":"string"},{"internalType":"string","name":"tokenBaseURI_","type":"string"},{"internalType":"address","name":"royaltyPayoutAddress_","type":"address"}],"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":"address","name":"newTrustee","type":"address"}],"name":"TrusteeChanged","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"artistOf","outputs":[{"internalType":"address","name":"artist","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"r_","type":"bytes32"},{"internalType":"bytes32","name":"s_","type":"bytes32"},{"internalType":"uint8","name":"v_","type":"uint8"},{"internalType":"uint32","name":"userID_","type":"uint32"},{"internalType":"uint32","name":"crayonID_","type":"uint32"},{"internalType":"uint32","name":"editionNumber_","type":"uint32"},{"internalType":"uint32","name":"royaltyAggBPS_","type":"uint32"},{"internalType":"address","name":"artist_","type":"address"},{"internalType":"string","name":"ipfsCid_","type":"string"}],"name":"authorizedMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"artistID_","type":"uint256"}],"name":"getTokensByArtistID","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"crayonId_","type":"uint256"}],"name":"getTokensByCrayonID","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"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":"isMintable","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":[],"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":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyPayoutAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"contractURI_","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isMintable_","type":"bool"}],"name":"setMintable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"payoutAddress_","type":"address"}],"name":"setRoyaltyPayoutAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"name":"setTokenBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTrustee_","type":"address"}],"name":"setTrustee","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":[],"name":"tokenBaseURI","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":[{"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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokens","outputs":[{"internalType":"uint32","name":"artistID","type":"uint32"},{"internalType":"uint32","name":"crayonID","type":"uint32"},{"internalType":"uint32","name":"editionNumber","type":"uint32"},{"internalType":"uint32","name":"royaltyAggBPS","type":"uint32"},{"internalType":"address","name":"artist","type":"address"},{"internalType":"string","name":"ipfsCID","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokensByArtistID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokensByCrayonID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"trustee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

6080604052600c805460ff60a01b1916600160a01b1790553480156200002457600080fd5b506040516200307c3803806200307c83398101604081905262000047916200031e565b84518590859062000060906000906020850190620001ab565b50805162000076906001906020840190620001ab565b505050620000936200008d6200015560201b60201c565b62000159565b600b80546001600160a01b03191690556001600160a01b038116620000fe5760405162461bcd60e51b815260206004820152601660248201527f696e76616c6964207061796f7574206164647265737300000000000000000000604482015260640160405180910390fd5b825162000113906010906020860190620001ab565b50815162000129906011906020850190620001ab565b50600c80546001600160a01b0319166001600160a01b0392909216919091179055506200043892505050565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620001b990620003fb565b90600052602060002090601f016020900481019282620001dd576000855562000228565b82601f10620001f857805160ff191683800117855562000228565b8280016001018555821562000228579182015b82811115620002285782518255916020019190600101906200020b565b50620002369291506200023a565b5090565b5b808211156200023657600081556001016200023b565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200027957600080fd5b81516001600160401b038082111562000296576200029662000251565b604051601f8301601f19908116603f01168101908282118183101715620002c157620002c162000251565b81604052838152602092508683858801011115620002de57600080fd5b600091505b83821015620003025785820183015181830184015290820190620002e3565b83821115620003145760008385830101525b9695505050505050565b600080600080600060a086880312156200033757600080fd5b85516001600160401b03808211156200034f57600080fd5b6200035d89838a0162000267565b965060208801519150808211156200037457600080fd5b6200038289838a0162000267565b955060408801519150808211156200039957600080fd5b620003a789838a0162000267565b94506060880151915080821115620003be57600080fd5b50620003cd8882890162000267565b608088015190935090506001600160a01b0381168114620003ed57600080fd5b809150509295509295909350565b600181811c908216806200041057607f821691505b602082108114156200043257634e487b7160e01b600052602260045260246000fd5b50919050565b612c3480620004486000396000f3fe608060405234801561001057600080fd5b50600436106101c25760003560e01c806301ffc9a7146101c757806306fdde03146101ef578063081812fc14610204578063095ea7b31461022457806318160ddd1461023957806323b872dd1461024b578063285d70d41461025e57806329dec8c0146102715780632a55205a146102915780632f745c59146102c35780633e6a333a146102d65780633f6805ba146102e957806342842e0e146102fc57806342966c681461030f57806345aeefde1461032257806346b45af7146103355780634e99b800146103495780634f64b2be146103515780634f6ccce7146103765780635370c0a2146103895780636352211e1461039c57806366ab47da146103af57806370a08231146103c2578063715018a6146103d55780637db3e1a5146103dd5780638da5cb5b146103f05780638ef79e91146103f8578063938e3d7b1461040b57806395d89b411461041e578063a22cb46514610426578063b18bae8014610439578063b88d4fde1461044c578063c87b56dd1461045f578063d0d1ea7014610472578063e8a3d48514610485578063e985e9c51461048d578063f2fde38b146104a0578063fdf97cb2146104b3575b600080fd5b6101da6101d5366004612421565b6104c6565b60405190151581526020015b60405180910390f35b6101f76104f1565b6040516101e6919061249d565b6102176102123660046124b0565b610583565b6040516101e691906124c9565b6102376102323660046124f9565b610610565b005b6008545b6040519081526020016101e6565b610237610259366004612523565b610721565b61023761026c36600461256f565b610752565b61028461027f3660046124b0565b6107aa565b6040516101e6919061258a565b6102a461029f3660046125ce565b61080c565b604080516001600160a01b0390931683526020830191909152016101e6565b61023d6102d13660046124f9565b6109c2565b61023d6102e43660046125ce565b610a58565b600c54610217906001600160a01b031681565b61023761030a366004612523565b610a89565b61023761031d3660046124b0565b610aa4565b6102376103303660046125f0565b610af7565b600c546101da90600160a01b900460ff1681565b6101f7610ba2565b61036461035f3660046124b0565b610c30565b6040516101e69695949392919061260b565b61023d6103843660046124b0565b610d0f565b6102176103973660046124b0565b610da2565b6102176103aa3660046124b0565b610e0a565b6102846103bd3660046124b0565b610e81565b61023d6103d03660046125f0565b610ee1565b610237610f68565b6102376103eb366004612673565b610fa3565b61021761127d565b6102376104063660046127f0565b61128c565b6102376104193660046127f0565b6112dd565b6101f761132a565b610237610434366004612838565b611339565b61023d6104473660046125ce565b6113fa565b61023761045a36600461286b565b611416565b6101f761046d3660046124b0565b61144e565b6102376104803660046125f0565b61158a565b6101f761160f565b6101da61049b3660046128e6565b61161e565b6102376104ae3660046125f0565b61164c565b600b54610217906001600160a01b031681565b60006001600160e01b0319821663780e9d6360e01b14806104eb57506104eb826116e9565b92915050565b60606000805461050090612910565b80601f016020809104026020016040519081016040528092919081815260200182805461052c90612910565b80156105795780601f1061054e57610100808354040283529160200191610579565b820191906000526020600020905b81548152906001019060200180831161055c57829003601f168201915b5050505050905090565b600061058e82611739565b6105f45760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061061b82610e0a565b9050806001600160a01b0316836001600160a01b031614156106895760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016105eb565b336001600160a01b03821614806106a557506106a5813361161e565b6107125760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b60648201526084016105eb565b61071c8383611756565b505050565b61072b33826117c4565b6107475760405162461bcd60e51b81526004016105eb9061294b565b61071c83838361188e565b600b546001600160a01b0316331480610783575061076e61127d565b6001600160a01b0316336001600160a01b0316145b61078c57600080fd5b600c8054911515600160a01b0260ff60a01b19909216919091179055565b6000818152600f602090815260409182902080548351818402810184019094528084526060939283018282801561080057602002820191906000526020600020905b8154815260200190600101908083116107ec575b50505050509050919050565b60008061081884611739565b61087f5760405162461bcd60e51b815260206004820152603260248201527f49455243323938313a20726f79616c747920696e666f20717565727920666f72604482015271103737b732bc34b9ba32b73a103a37b5b2b760711b60648201526084016105eb565b6000848152600d60209081526040808320815160c081018352815463ffffffff8082168352600160201b8204811695830195909552600160401b8104851693820193909352600160601b909204909216606082015260018201546001600160a01b0316608082015260028201805491929160a0840191906108ff90612910565b80601f016020809104026020016040519081016040528092919081815260200182805461092b90612910565b80156109785780601f1061094d57610100808354040283529160200191610978565b820191906000526020600020905b81548152906001019060200180831161095b57829003601f168201915b505050919092525050600c5460608301516001600160a01b039091169550919250612710916109ae915063ffffffff16866129b2565b6109b891906129d1565b9150509250929050565b60006109cd83610ee1565b8210610a2f5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b60648201526084016105eb565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600f6020528160005260406000208181548110610a7457600080fd5b90600052602060002001600091509150505481565b61071c83838360405180602001604052806000815250611416565b610aae33826117c4565b610aeb5760405162461bcd60e51b815260206004820152600e60248201526d139bdd08185d5d1a1bdc9a5e995960921b60448201526064016105eb565b610af481611a27565b50565b600b546001600160a01b0316331480610b285750610b1361127d565b6001600160a01b0316336001600160a01b0316145b610b3157600080fd5b6001600160a01b038116610b805760405162461bcd60e51b8152602060048201526016602482015275696e76616c6964207061796f7574206164647265737360501b60448201526064016105eb565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b60118054610baf90612910565b80601f0160208091040260200160405190810160405280929190818152602001828054610bdb90612910565b8015610c285780601f10610bfd57610100808354040283529160200191610c28565b820191906000526020600020905b815481529060010190602001808311610c0b57829003601f168201915b505050505081565b600d6020526000908152604090208054600182015460028301805463ffffffff80851695600160201b8604821695600160401b8104831695600160601b909104909216936001600160a01b0390921692909190610c8c90612910565b80601f0160208091040260200160405190810160405280929190818152602001828054610cb890612910565b8015610d055780601f10610cda57610100808354040283529160200191610d05565b820191906000526020600020905b815481529060010190602001808311610ce857829003601f168201915b5050505050905086565b6000610d1a60085490565b8210610d7d5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b60648201526084016105eb565b60088281548110610d9057610d906129f3565b90600052602060002001549050919050565b6000610dad82611739565b610deb5760405162461bcd60e51b815260206004820152600f60248201526e151bdad95b881b9bdd08199bdd5b99608a1b60448201526064016105eb565b506000908152600d60205260409020600101546001600160a01b031690565b6000818152600260205260408120546001600160a01b0316806104eb5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016105eb565b6000818152600e602090815260409182902080548351818402810184019094528084526060939283018282801561080057602002820191906000526020600020908154815260200190600101908083116107ec5750505050509050919050565b60006001600160a01b038216610f4c5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016105eb565b506001600160a01b031660009081526003602052604090205490565b33610f7161127d565b6001600160a01b031614610f975760405162461bcd60e51b81526004016105eb90612a09565b610fa16000611abc565b565b600c54600160a01b900460ff16610ffb5760405162461bcd60e51b815260206004820152601c60248201527b36b4b73a34b73390383937b1b2b9b99034b9903337b93134b23232b760211b60448201526064016105eb565b6000338888888888888860405160200161101c989796959493929190612a3e565b604051602081830303815290604052805190602001209050611040818c8c8c611b0e565b61109a5760405162461bcd60e51b815260206004820152602560248201527f746865206d696e74696e672072657175657374206973206e6f7420617574686f6044820152641c9a5e995960da1b60648201526084016105eb565b60008663ffffffff168863ffffffff16620186a06110b891906129b2565b6110c29190612ab2565b905060006040518060c001604052808b63ffffffff1681526020018a63ffffffff1681526020018963ffffffff1681526020018863ffffffff168152602001876001600160a01b0316815260200186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093909452505063ffffffff808e168252600f60209081526040808420805460018181018355918652838620018990558f84168552600e83528185208054808301825590865283862001899055888552600d83529381902086518154848901519389015160608a01518716600160601b0263ffffffff60601b19918816600160401b0291909116600160401b600160801b0319958816600160201b026001600160401b03199093169390971692909217179290921693909317178255608085015192820180546001600160a01b039094166001600160a01b03199094169390931790925560a084015180519495508594919350611245926002850192910190612372565b509050506112538683611bb3565b61126e86338460405180602001604052806000815250611bcd565b50505050505050505050505050565b600a546001600160a01b031690565b600b546001600160a01b03163314806112bd57506112a861127d565b6001600160a01b0316336001600160a01b0316145b6112c657600080fd5b80516112d9906011906020840190612372565b5050565b600b546001600160a01b031633148061130e57506112f961127d565b6001600160a01b0316336001600160a01b0316145b61131757600080fd5b80516112d9906010906020840190612372565b60606001805461050090612910565b6001600160a01b03821633141561138e5760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b60448201526064016105eb565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600e6020528160005260406000208181548110610a7457600080fd5b61142033836117c4565b61143c5760405162461bcd60e51b81526004016105eb9061294b565b61144884848484611bcd565b50505050565b606061145982611739565b6114bd5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016105eb565b6000828152600d6020526040812060020180546114d990612910565b80601f016020809104026020016040519081016040528092919081815260200182805461150590612910565b80156115525780601f1061152757610100808354040283529160200191611552565b820191906000526020600020905b81548152906001019060200180831161153557829003601f168201915b50505050509050611561611c00565b81604051602001611573929190612aca565b604051602081830303815290604052915050919050565b3361159361127d565b6001600160a01b0316146115b95760405162461bcd60e51b81526004016105eb90612a09565b600b80546001600160a01b0319166001600160a01b0383161790556040517fc733fbf62b4701c9ad4b293962373da054d7546a3a5bf7eb58074da7fa65cc4c906116049083906124c9565b60405180910390a150565b60606010805461050090612910565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3361165561127d565b6001600160a01b03161461167b5760405162461bcd60e51b81526004016105eb90612a09565b6001600160a01b0381166116e05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105eb565b610af481611abc565b60006001600160e01b031982166380ac58cd60e01b148061171a57506001600160e01b03198216635b5e139f60e01b145b806104eb57506301ffc9a760e01b6001600160e01b03198316146104eb565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061178b82610e0a565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006117cf82611739565b6118305760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016105eb565b600061183b83610e0a565b9050806001600160a01b0316846001600160a01b031614806118765750836001600160a01b031661186b84610583565b6001600160a01b0316145b806118865750611886818561161e565b949350505050565b826001600160a01b03166118a182610e0a565b6001600160a01b0316146119095760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016105eb565b6001600160a01b03821661196b5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016105eb565b611976838383611c0f565b611981600082611756565b6001600160a01b03831660009081526003602052604081208054600192906119aa908490612af9565b90915550506001600160a01b03821660009081526003602052604081208054600192906119d8908490612ab2565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b038681169182179092559151849391871691600080516020612bdf83398151915291a4505050565b6000611a3282610e0a565b9050611a4081600084611c0f565b611a4b600083611756565b6001600160a01b0381166000908152600360205260408120805460019290611a74908490612af9565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b03841690600080516020612bdf833981519152908390a45050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600080611b72611b6a876040517b0ca2ba3432b932bab69029b4b3b732b21026b2b9b9b0b3b29d05199960211b6020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b848787611cc7565b600b549091506001600160a01b0380831691161480611ba95750611b9461127d565b6001600160a01b0316816001600160a01b0316145b9695505050505050565b6112d9828260405180602001604052806000815250611cef565b611bd884848461188e565b611be484848484611d22565b6114485760405162461bcd60e51b81526004016105eb90612b10565b60606011805461050090612910565b6001600160a01b038316611c6a57611c6581600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b611c8d565b816001600160a01b0316836001600160a01b031614611c8d57611c8d8382611e1d565b6001600160a01b038216611ca45761071c81611eba565b826001600160a01b0316826001600160a01b03161461071c5761071c8282611f69565b6000806000611cd887878787611fad565b91509150611ce581612090565b5095945050505050565b611cf98383612246565b611d066000848484611d22565b61071c5760405162461bcd60e51b81526004016105eb90612b10565b60006001600160a01b0384163b15611e1557604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611d66903390899088908890600401612b62565b6020604051808303816000875af1925050508015611da1575060408051601f3d908101601f19168201909252611d9e91810190612b95565b60015b611dfb573d808015611dcf576040519150601f19603f3d011682016040523d82523d6000602084013e611dd4565b606091505b508051611df35760405162461bcd60e51b81526004016105eb90612b10565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611886565b506001611886565b60006001611e2a84610ee1565b611e349190612af9565b600083815260076020526040902054909150808214611e87576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090611ecc90600190612af9565b60008381526009602052604081205460088054939450909284908110611ef457611ef46129f3565b906000526020600020015490508060088381548110611f1557611f156129f3565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480611f4d57611f4d612bb2565b6001900381819060005260206000200160009055905550505050565b6000611f7483610ee1565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6000806fa2a8918ca85bafe22016d0b997e4df60600160ff1b03831115611fda5750600090506003612087565b8460ff16601b14158015611ff257508460ff16601c14155b156120035750600090506004612087565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612057573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661208057600060019250925050612087565b9150600090505b94509492505050565b60008160048111156120a4576120a4612bc8565b14156120ad5750565b60018160048111156120c1576120c1612bc8565b141561210a5760405162461bcd60e51b815260206004820152601860248201527745434453413a20696e76616c6964207369676e617475726560401b60448201526064016105eb565b600281600481111561211e5761211e612bc8565b141561216c5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105eb565b600381600481111561218057612180612bc8565b14156121d95760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016105eb565b60048160048111156121ed576121ed612bc8565b1415610af45760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016105eb565b6001600160a01b03821661229c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016105eb565b6122a581611739565b156122f15760405162461bcd60e51b815260206004820152601c60248201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b60448201526064016105eb565b6122fd60008383611c0f565b6001600160a01b0382166000908152600360205260408120805460019290612326908490612ab2565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051839290600080516020612bdf833981519152908290a45050565b82805461237e90612910565b90600052602060002090601f0160209004810192826123a057600085556123e6565b82601f106123b957805160ff19168380011785556123e6565b828001600101855582156123e6579182015b828111156123e65782518255916020019190600101906123cb565b506123f29291506123f6565b5090565b5b808211156123f257600081556001016123f7565b6001600160e01b031981168114610af457600080fd5b60006020828403121561243357600080fd5b813561243e8161240b565b9392505050565b60005b83811015612460578181015183820152602001612448565b838111156114485750506000910152565b60008151808452612489816020860160208601612445565b601f01601f19169290920160200192915050565b60208152600061243e6020830184612471565b6000602082840312156124c257600080fd5b5035919050565b6001600160a01b0391909116815260200190565b80356001600160a01b03811681146124f457600080fd5b919050565b6000806040838503121561250c57600080fd5b612515836124dd565b946020939093013593505050565b60008060006060848603121561253857600080fd5b612541846124dd565b925061254f602085016124dd565b9150604084013590509250925092565b803580151581146124f457600080fd5b60006020828403121561258157600080fd5b61243e8261255f565b6020808252825182820181905260009190848201906040850190845b818110156125c2578351835292840192918401916001016125a6565b50909695505050505050565b600080604083850312156125e157600080fd5b50508035926020909101359150565b60006020828403121561260257600080fd5b61243e826124dd565b63ffffffff878116825286811660208301528581166040830152841660608201526001600160a01b038316608082015260c060a0820181905260009061265390830184612471565b98975050505050505050565b803563ffffffff811681146124f457600080fd5b6000806000806000806000806000806101208b8d03121561269357600080fd5b8a35995060208b0135985060408b013560ff811681146126b257600080fd5b97506126c060608c0161265f565b96506126ce60808c0161265f565b95506126dc60a08c0161265f565b94506126ea60c08c0161265f565b93506126f860e08c016124dd565b92506101008b01356001600160401b038082111561271557600080fd5b818d0191508d601f83011261272957600080fd5b81358181111561273857600080fd5b8e602082850101111561274a57600080fd5b6020830194508093505050509295989b9194979a5092959850565b634e487b7160e01b600052604160045260246000fd5b60006001600160401b038084111561279557612795612765565b604051601f8501601f19908116603f011681019082821181831017156127bd576127bd612765565b816040528093508581528686860111156127d657600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561280257600080fd5b81356001600160401b0381111561281857600080fd5b8201601f8101841361282957600080fd5b6118868482356020840161277b565b6000806040838503121561284b57600080fd5b612854836124dd565b91506128626020840161255f565b90509250929050565b6000806000806080858703121561288157600080fd5b61288a856124dd565b9350612898602086016124dd565b92506040850135915060608501356001600160401b038111156128ba57600080fd5b8501601f810187136128cb57600080fd5b6128da8782356020840161277b565b91505092959194509250565b600080604083850312156128f957600080fd5b612902836124dd565b9150612862602084016124dd565b600181811c9082168061292457607f821691505b6020821081141561294557634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156129cc576129cc61299c565b500290565b6000826129ee57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6001600160a01b03898116825263ffffffff89811660208401528881166040840152878116606084015286166080830152841660a082015260e060c08201819052810182905260006101008385828501376000838501820152601f909301601f191690910190910198975050505050505050565b60008219821115612ac557612ac561299c565b500190565b60008351612adc818460208801612445565b835190830190612af0818360208801612445565b01949350505050565b600082821015612b0b57612b0b61299c565b500390565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611ba990830184612471565b600060208284031215612ba757600080fd5b815161243e8161240b565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220ed3294993fb30295ba186822fb80fbe1264812a2d5e670dc3fc4096c5e356cad64736f6c634300080a003300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000180000000000000000000000000124cc966ebac6bd32a2c90fa5fd48c96ad9e033c000000000000000000000000000000000000000000000000000000000000000f437261796f6e20436f64657320763100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006435241594f4e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003068747470733a2f2f6f70656e70726f63657373696e672e6f72672f637261796f6e2f636f6e74726163744d6574612f31000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007697066733a2f2f00000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101c25760003560e01c806301ffc9a7146101c757806306fdde03146101ef578063081812fc14610204578063095ea7b31461022457806318160ddd1461023957806323b872dd1461024b578063285d70d41461025e57806329dec8c0146102715780632a55205a146102915780632f745c59146102c35780633e6a333a146102d65780633f6805ba146102e957806342842e0e146102fc57806342966c681461030f57806345aeefde1461032257806346b45af7146103355780634e99b800146103495780634f64b2be146103515780634f6ccce7146103765780635370c0a2146103895780636352211e1461039c57806366ab47da146103af57806370a08231146103c2578063715018a6146103d55780637db3e1a5146103dd5780638da5cb5b146103f05780638ef79e91146103f8578063938e3d7b1461040b57806395d89b411461041e578063a22cb46514610426578063b18bae8014610439578063b88d4fde1461044c578063c87b56dd1461045f578063d0d1ea7014610472578063e8a3d48514610485578063e985e9c51461048d578063f2fde38b146104a0578063fdf97cb2146104b3575b600080fd5b6101da6101d5366004612421565b6104c6565b60405190151581526020015b60405180910390f35b6101f76104f1565b6040516101e6919061249d565b6102176102123660046124b0565b610583565b6040516101e691906124c9565b6102376102323660046124f9565b610610565b005b6008545b6040519081526020016101e6565b610237610259366004612523565b610721565b61023761026c36600461256f565b610752565b61028461027f3660046124b0565b6107aa565b6040516101e6919061258a565b6102a461029f3660046125ce565b61080c565b604080516001600160a01b0390931683526020830191909152016101e6565b61023d6102d13660046124f9565b6109c2565b61023d6102e43660046125ce565b610a58565b600c54610217906001600160a01b031681565b61023761030a366004612523565b610a89565b61023761031d3660046124b0565b610aa4565b6102376103303660046125f0565b610af7565b600c546101da90600160a01b900460ff1681565b6101f7610ba2565b61036461035f3660046124b0565b610c30565b6040516101e69695949392919061260b565b61023d6103843660046124b0565b610d0f565b6102176103973660046124b0565b610da2565b6102176103aa3660046124b0565b610e0a565b6102846103bd3660046124b0565b610e81565b61023d6103d03660046125f0565b610ee1565b610237610f68565b6102376103eb366004612673565b610fa3565b61021761127d565b6102376104063660046127f0565b61128c565b6102376104193660046127f0565b6112dd565b6101f761132a565b610237610434366004612838565b611339565b61023d6104473660046125ce565b6113fa565b61023761045a36600461286b565b611416565b6101f761046d3660046124b0565b61144e565b6102376104803660046125f0565b61158a565b6101f761160f565b6101da61049b3660046128e6565b61161e565b6102376104ae3660046125f0565b61164c565b600b54610217906001600160a01b031681565b60006001600160e01b0319821663780e9d6360e01b14806104eb57506104eb826116e9565b92915050565b60606000805461050090612910565b80601f016020809104026020016040519081016040528092919081815260200182805461052c90612910565b80156105795780601f1061054e57610100808354040283529160200191610579565b820191906000526020600020905b81548152906001019060200180831161055c57829003601f168201915b5050505050905090565b600061058e82611739565b6105f45760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061061b82610e0a565b9050806001600160a01b0316836001600160a01b031614156106895760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016105eb565b336001600160a01b03821614806106a557506106a5813361161e565b6107125760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b60648201526084016105eb565b61071c8383611756565b505050565b61072b33826117c4565b6107475760405162461bcd60e51b81526004016105eb9061294b565b61071c83838361188e565b600b546001600160a01b0316331480610783575061076e61127d565b6001600160a01b0316336001600160a01b0316145b61078c57600080fd5b600c8054911515600160a01b0260ff60a01b19909216919091179055565b6000818152600f602090815260409182902080548351818402810184019094528084526060939283018282801561080057602002820191906000526020600020905b8154815260200190600101908083116107ec575b50505050509050919050565b60008061081884611739565b61087f5760405162461bcd60e51b815260206004820152603260248201527f49455243323938313a20726f79616c747920696e666f20717565727920666f72604482015271103737b732bc34b9ba32b73a103a37b5b2b760711b60648201526084016105eb565b6000848152600d60209081526040808320815160c081018352815463ffffffff8082168352600160201b8204811695830195909552600160401b8104851693820193909352600160601b909204909216606082015260018201546001600160a01b0316608082015260028201805491929160a0840191906108ff90612910565b80601f016020809104026020016040519081016040528092919081815260200182805461092b90612910565b80156109785780601f1061094d57610100808354040283529160200191610978565b820191906000526020600020905b81548152906001019060200180831161095b57829003601f168201915b505050919092525050600c5460608301516001600160a01b039091169550919250612710916109ae915063ffffffff16866129b2565b6109b891906129d1565b9150509250929050565b60006109cd83610ee1565b8210610a2f5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b60648201526084016105eb565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600f6020528160005260406000208181548110610a7457600080fd5b90600052602060002001600091509150505481565b61071c83838360405180602001604052806000815250611416565b610aae33826117c4565b610aeb5760405162461bcd60e51b815260206004820152600e60248201526d139bdd08185d5d1a1bdc9a5e995960921b60448201526064016105eb565b610af481611a27565b50565b600b546001600160a01b0316331480610b285750610b1361127d565b6001600160a01b0316336001600160a01b0316145b610b3157600080fd5b6001600160a01b038116610b805760405162461bcd60e51b8152602060048201526016602482015275696e76616c6964207061796f7574206164647265737360501b60448201526064016105eb565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b60118054610baf90612910565b80601f0160208091040260200160405190810160405280929190818152602001828054610bdb90612910565b8015610c285780601f10610bfd57610100808354040283529160200191610c28565b820191906000526020600020905b815481529060010190602001808311610c0b57829003601f168201915b505050505081565b600d6020526000908152604090208054600182015460028301805463ffffffff80851695600160201b8604821695600160401b8104831695600160601b909104909216936001600160a01b0390921692909190610c8c90612910565b80601f0160208091040260200160405190810160405280929190818152602001828054610cb890612910565b8015610d055780601f10610cda57610100808354040283529160200191610d05565b820191906000526020600020905b815481529060010190602001808311610ce857829003601f168201915b5050505050905086565b6000610d1a60085490565b8210610d7d5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b60648201526084016105eb565b60088281548110610d9057610d906129f3565b90600052602060002001549050919050565b6000610dad82611739565b610deb5760405162461bcd60e51b815260206004820152600f60248201526e151bdad95b881b9bdd08199bdd5b99608a1b60448201526064016105eb565b506000908152600d60205260409020600101546001600160a01b031690565b6000818152600260205260408120546001600160a01b0316806104eb5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016105eb565b6000818152600e602090815260409182902080548351818402810184019094528084526060939283018282801561080057602002820191906000526020600020908154815260200190600101908083116107ec5750505050509050919050565b60006001600160a01b038216610f4c5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016105eb565b506001600160a01b031660009081526003602052604090205490565b33610f7161127d565b6001600160a01b031614610f975760405162461bcd60e51b81526004016105eb90612a09565b610fa16000611abc565b565b600c54600160a01b900460ff16610ffb5760405162461bcd60e51b815260206004820152601c60248201527b36b4b73a34b73390383937b1b2b9b99034b9903337b93134b23232b760211b60448201526064016105eb565b6000338888888888888860405160200161101c989796959493929190612a3e565b604051602081830303815290604052805190602001209050611040818c8c8c611b0e565b61109a5760405162461bcd60e51b815260206004820152602560248201527f746865206d696e74696e672072657175657374206973206e6f7420617574686f6044820152641c9a5e995960da1b60648201526084016105eb565b60008663ffffffff168863ffffffff16620186a06110b891906129b2565b6110c29190612ab2565b905060006040518060c001604052808b63ffffffff1681526020018a63ffffffff1681526020018963ffffffff1681526020018863ffffffff168152602001876001600160a01b0316815260200186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093909452505063ffffffff808e168252600f60209081526040808420805460018181018355918652838620018990558f84168552600e83528185208054808301825590865283862001899055888552600d83529381902086518154848901519389015160608a01518716600160601b0263ffffffff60601b19918816600160401b0291909116600160401b600160801b0319958816600160201b026001600160401b03199093169390971692909217179290921693909317178255608085015192820180546001600160a01b039094166001600160a01b03199094169390931790925560a084015180519495508594919350611245926002850192910190612372565b509050506112538683611bb3565b61126e86338460405180602001604052806000815250611bcd565b50505050505050505050505050565b600a546001600160a01b031690565b600b546001600160a01b03163314806112bd57506112a861127d565b6001600160a01b0316336001600160a01b0316145b6112c657600080fd5b80516112d9906011906020840190612372565b5050565b600b546001600160a01b031633148061130e57506112f961127d565b6001600160a01b0316336001600160a01b0316145b61131757600080fd5b80516112d9906010906020840190612372565b60606001805461050090612910565b6001600160a01b03821633141561138e5760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b60448201526064016105eb565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600e6020528160005260406000208181548110610a7457600080fd5b61142033836117c4565b61143c5760405162461bcd60e51b81526004016105eb9061294b565b61144884848484611bcd565b50505050565b606061145982611739565b6114bd5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016105eb565b6000828152600d6020526040812060020180546114d990612910565b80601f016020809104026020016040519081016040528092919081815260200182805461150590612910565b80156115525780601f1061152757610100808354040283529160200191611552565b820191906000526020600020905b81548152906001019060200180831161153557829003601f168201915b50505050509050611561611c00565b81604051602001611573929190612aca565b604051602081830303815290604052915050919050565b3361159361127d565b6001600160a01b0316146115b95760405162461bcd60e51b81526004016105eb90612a09565b600b80546001600160a01b0319166001600160a01b0383161790556040517fc733fbf62b4701c9ad4b293962373da054d7546a3a5bf7eb58074da7fa65cc4c906116049083906124c9565b60405180910390a150565b60606010805461050090612910565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3361165561127d565b6001600160a01b03161461167b5760405162461bcd60e51b81526004016105eb90612a09565b6001600160a01b0381166116e05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105eb565b610af481611abc565b60006001600160e01b031982166380ac58cd60e01b148061171a57506001600160e01b03198216635b5e139f60e01b145b806104eb57506301ffc9a760e01b6001600160e01b03198316146104eb565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061178b82610e0a565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006117cf82611739565b6118305760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016105eb565b600061183b83610e0a565b9050806001600160a01b0316846001600160a01b031614806118765750836001600160a01b031661186b84610583565b6001600160a01b0316145b806118865750611886818561161e565b949350505050565b826001600160a01b03166118a182610e0a565b6001600160a01b0316146119095760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016105eb565b6001600160a01b03821661196b5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016105eb565b611976838383611c0f565b611981600082611756565b6001600160a01b03831660009081526003602052604081208054600192906119aa908490612af9565b90915550506001600160a01b03821660009081526003602052604081208054600192906119d8908490612ab2565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b038681169182179092559151849391871691600080516020612bdf83398151915291a4505050565b6000611a3282610e0a565b9050611a4081600084611c0f565b611a4b600083611756565b6001600160a01b0381166000908152600360205260408120805460019290611a74908490612af9565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b03841690600080516020612bdf833981519152908390a45050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600080611b72611b6a876040517b0ca2ba3432b932bab69029b4b3b732b21026b2b9b9b0b3b29d05199960211b6020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b848787611cc7565b600b549091506001600160a01b0380831691161480611ba95750611b9461127d565b6001600160a01b0316816001600160a01b0316145b9695505050505050565b6112d9828260405180602001604052806000815250611cef565b611bd884848461188e565b611be484848484611d22565b6114485760405162461bcd60e51b81526004016105eb90612b10565b60606011805461050090612910565b6001600160a01b038316611c6a57611c6581600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b611c8d565b816001600160a01b0316836001600160a01b031614611c8d57611c8d8382611e1d565b6001600160a01b038216611ca45761071c81611eba565b826001600160a01b0316826001600160a01b03161461071c5761071c8282611f69565b6000806000611cd887878787611fad565b91509150611ce581612090565b5095945050505050565b611cf98383612246565b611d066000848484611d22565b61071c5760405162461bcd60e51b81526004016105eb90612b10565b60006001600160a01b0384163b15611e1557604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611d66903390899088908890600401612b62565b6020604051808303816000875af1925050508015611da1575060408051601f3d908101601f19168201909252611d9e91810190612b95565b60015b611dfb573d808015611dcf576040519150601f19603f3d011682016040523d82523d6000602084013e611dd4565b606091505b508051611df35760405162461bcd60e51b81526004016105eb90612b10565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611886565b506001611886565b60006001611e2a84610ee1565b611e349190612af9565b600083815260076020526040902054909150808214611e87576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090611ecc90600190612af9565b60008381526009602052604081205460088054939450909284908110611ef457611ef46129f3565b906000526020600020015490508060088381548110611f1557611f156129f3565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480611f4d57611f4d612bb2565b6001900381819060005260206000200160009055905550505050565b6000611f7483610ee1565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6000806fa2a8918ca85bafe22016d0b997e4df60600160ff1b03831115611fda5750600090506003612087565b8460ff16601b14158015611ff257508460ff16601c14155b156120035750600090506004612087565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612057573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661208057600060019250925050612087565b9150600090505b94509492505050565b60008160048111156120a4576120a4612bc8565b14156120ad5750565b60018160048111156120c1576120c1612bc8565b141561210a5760405162461bcd60e51b815260206004820152601860248201527745434453413a20696e76616c6964207369676e617475726560401b60448201526064016105eb565b600281600481111561211e5761211e612bc8565b141561216c5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105eb565b600381600481111561218057612180612bc8565b14156121d95760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016105eb565b60048160048111156121ed576121ed612bc8565b1415610af45760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016105eb565b6001600160a01b03821661229c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016105eb565b6122a581611739565b156122f15760405162461bcd60e51b815260206004820152601c60248201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b60448201526064016105eb565b6122fd60008383611c0f565b6001600160a01b0382166000908152600360205260408120805460019290612326908490612ab2565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051839290600080516020612bdf833981519152908290a45050565b82805461237e90612910565b90600052602060002090601f0160209004810192826123a057600085556123e6565b82601f106123b957805160ff19168380011785556123e6565b828001600101855582156123e6579182015b828111156123e65782518255916020019190600101906123cb565b506123f29291506123f6565b5090565b5b808211156123f257600081556001016123f7565b6001600160e01b031981168114610af457600080fd5b60006020828403121561243357600080fd5b813561243e8161240b565b9392505050565b60005b83811015612460578181015183820152602001612448565b838111156114485750506000910152565b60008151808452612489816020860160208601612445565b601f01601f19169290920160200192915050565b60208152600061243e6020830184612471565b6000602082840312156124c257600080fd5b5035919050565b6001600160a01b0391909116815260200190565b80356001600160a01b03811681146124f457600080fd5b919050565b6000806040838503121561250c57600080fd5b612515836124dd565b946020939093013593505050565b60008060006060848603121561253857600080fd5b612541846124dd565b925061254f602085016124dd565b9150604084013590509250925092565b803580151581146124f457600080fd5b60006020828403121561258157600080fd5b61243e8261255f565b6020808252825182820181905260009190848201906040850190845b818110156125c2578351835292840192918401916001016125a6565b50909695505050505050565b600080604083850312156125e157600080fd5b50508035926020909101359150565b60006020828403121561260257600080fd5b61243e826124dd565b63ffffffff878116825286811660208301528581166040830152841660608201526001600160a01b038316608082015260c060a0820181905260009061265390830184612471565b98975050505050505050565b803563ffffffff811681146124f457600080fd5b6000806000806000806000806000806101208b8d03121561269357600080fd5b8a35995060208b0135985060408b013560ff811681146126b257600080fd5b97506126c060608c0161265f565b96506126ce60808c0161265f565b95506126dc60a08c0161265f565b94506126ea60c08c0161265f565b93506126f860e08c016124dd565b92506101008b01356001600160401b038082111561271557600080fd5b818d0191508d601f83011261272957600080fd5b81358181111561273857600080fd5b8e602082850101111561274a57600080fd5b6020830194508093505050509295989b9194979a5092959850565b634e487b7160e01b600052604160045260246000fd5b60006001600160401b038084111561279557612795612765565b604051601f8501601f19908116603f011681019082821181831017156127bd576127bd612765565b816040528093508581528686860111156127d657600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561280257600080fd5b81356001600160401b0381111561281857600080fd5b8201601f8101841361282957600080fd5b6118868482356020840161277b565b6000806040838503121561284b57600080fd5b612854836124dd565b91506128626020840161255f565b90509250929050565b6000806000806080858703121561288157600080fd5b61288a856124dd565b9350612898602086016124dd565b92506040850135915060608501356001600160401b038111156128ba57600080fd5b8501601f810187136128cb57600080fd5b6128da8782356020840161277b565b91505092959194509250565b600080604083850312156128f957600080fd5b612902836124dd565b9150612862602084016124dd565b600181811c9082168061292457607f821691505b6020821081141561294557634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156129cc576129cc61299c565b500290565b6000826129ee57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6001600160a01b03898116825263ffffffff89811660208401528881166040840152878116606084015286166080830152841660a082015260e060c08201819052810182905260006101008385828501376000838501820152601f909301601f191690910190910198975050505050505050565b60008219821115612ac557612ac561299c565b500190565b60008351612adc818460208801612445565b835190830190612af0818360208801612445565b01949350505050565b600082821015612b0b57612b0b61299c565b500390565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611ba990830184612471565b600060208284031215612ba757600080fd5b815161243e8161240b565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220ed3294993fb30295ba186822fb80fbe1264812a2d5e670dc3fc4096c5e356cad64736f6c634300080a0033

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

00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000180000000000000000000000000124cc966ebac6bd32a2c90fa5fd48c96ad9e033c000000000000000000000000000000000000000000000000000000000000000f437261796f6e20436f64657320763100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006435241594f4e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003068747470733a2f2f6f70656e70726f63657373696e672e6f72672f637261796f6e2f636f6e74726163744d6574612f31000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007697066733a2f2f00000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : title_ (string): Crayon Codes v1
Arg [1] : symbol_ (string): CRAYON
Arg [2] : contractURI_ (string): https://openprocessing.org/crayon/contractMeta/1
Arg [3] : tokenBaseURI_ (string): ipfs://
Arg [4] : royaltyPayoutAddress_ (address): 0x124cc966ebac6BD32a2c90FA5FD48C96Ad9e033c

-----Encoded View---------------
14 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [4] : 000000000000000000000000124cc966ebac6bd32a2c90fa5fd48c96ad9e033c
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000f
Arg [6] : 437261796f6e20436f6465732076310000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [8] : 435241594f4e0000000000000000000000000000000000000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000030
Arg [10] : 68747470733a2f2f6f70656e70726f63657373696e672e6f72672f637261796f
Arg [11] : 6e2f636f6e74726163744d6574612f3100000000000000000000000000000000
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [13] : 697066733a2f2f00000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

53502:8036:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37816:224;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;37816:224:0;;;;;;;;25708:100;;;:::i;:::-;;;;;;;:::i;27267:221::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;26790:411::-;;;;;;:::i;:::-;;:::i;:::-;;38456:113;38544:10;:17;38456:113;;;2319:25:1;;;2307:2;2292:18;38456:113:0;2173:177:1;28157:339:0;;;;;;:::i;:::-;;:::i;55556:106::-;;;;;;:::i;:::-;;:::i;58968:188::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;59848:493::-;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;4120:32:1;;;4102:51;;4184:2;4169:18;;4162:34;;;;4075:18;59848:493:0;3928:274:1;38124:256:0;;;;;;:::i;:::-;;:::i;54030:53::-;;;;;;:::i;:::-;;:::i;53608:35::-;;;;;-1:-1:-1;;;;;53608:35:0;;;28567:185;;;;;;:::i;:::-;;:::i;59246:167::-;;;;;;:::i;:::-;;:::i;55727:234::-;;;;;;:::i;:::-;;:::i;53650:29::-;;;;;-1:-1:-1;;;53650:29:0;;;;;;54149:26;;;:::i;53881:39::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;:::i;38646:233::-;;;;;;:::i;:::-;;:::i;58180:252::-;;;;;;:::i;:::-;;:::i;25402:239::-;;;;;;:::i;:::-;;:::i;58607:188::-;;;;;;:::i;:::-;;:::i;25132:208::-;;;;;;:::i;:::-;;:::i;4558:94::-;;;:::i;56676:1338::-;;;;;;:::i;:::-;;:::i;3907:87::-;;;:::i;60440:115::-;;;;;;:::i;:::-;;:::i;61218:145::-;;;;;;:::i;:::-;;:::i;25877:104::-;;;:::i;27560:295::-;;;;;;:::i;:::-;;:::i;53947:53::-;;;;;;:::i;:::-;;:::i;28823:328::-;;;;;;:::i;:::-;;:::i;60773:396::-;;;;;;:::i;:::-;;:::i;53301:145::-;;;;;;:::i;:::-;;:::i;61436:99::-;;;:::i;27926:164::-;;;;;;:::i;:::-;;:::i;4807:192::-;;;;;;:::i;:::-;;:::i;53087:22::-;;;;;-1:-1:-1;;;;;53087:22:0;;;37816:224;37918:4;-1:-1:-1;;;;;;37942:50:0;;-1:-1:-1;;;37942:50:0;;:90;;;37996:36;38020:11;37996:23;:36::i;:::-;37935:97;37816:224;-1:-1:-1;;37816:224:0:o;25708:100::-;25762:13;25795:5;25788:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25708:100;:::o;27267:221::-;27343:7;27371:16;27379:7;27371;:16::i;:::-;27363:73;;;;-1:-1:-1;;;27363:73:0;;9499:2:1;27363:73:0;;;9481:21:1;9538:2;9518:18;;;9511:30;9577:34;9557:18;;;9550:62;-1:-1:-1;;;9628:18:1;;;9621:42;9680:19;;27363:73:0;;;;;;;;;-1:-1:-1;27456:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;27456:24:0;;27267:221::o;26790:411::-;26871:13;26887:23;26902:7;26887:14;:23::i;:::-;26871:39;;26935:5;-1:-1:-1;;;;;26929:11:0;:2;-1:-1:-1;;;;;26929:11:0;;;26921:57;;;;-1:-1:-1;;;26921:57:0;;9912:2:1;26921:57:0;;;9894:21:1;9951:2;9931:18;;;9924:30;9990:34;9970:18;;;9963:62;-1:-1:-1;;;10041:18:1;;;10034:31;10082:19;;26921:57:0;9710:397:1;26921:57:0;2775:10;-1:-1:-1;;;;;27013:21:0;;;;:62;;-1:-1:-1;27038:37:0;27055:5;2775:10;27926:164;:::i;27038:37::-;26991:168;;;;-1:-1:-1;;;26991:168:0;;10314:2:1;26991:168:0;;;10296:21:1;10353:2;10333:18;;;10326:30;10392:34;10372:18;;;10365:62;-1:-1:-1;;;10443:18:1;;;10436:54;10507:19;;26991:168:0;10112:420:1;26991:168:0;27172:21;27181:2;27185:7;27172:8;:21::i;:::-;26860:341;26790:411;;:::o;28157:339::-;28352:41;2775:10;28385:7;28352:18;:41::i;:::-;28344:103;;;;-1:-1:-1;;;28344:103:0;;;;;;;:::i;:::-;28460:28;28470:4;28476:2;28480:7;28460:9;:28::i;55556:106::-;53240:7;;-1:-1:-1;;;;;53240:7:0;53226:10;:21;;:46;;;53265:7;:5;:7::i;:::-;-1:-1:-1;;;;;53251:21:0;:10;-1:-1:-1;;;;;53251:21:0;;53226:46;53218:55;;;;;;55630:10:::1;:24:::0;;;::::1;;-1:-1:-1::0;;;55630:24:0::1;-1:-1:-1::0;;;;55630:24:0;;::::1;::::0;;;::::1;::::0;;55556:106::o;58968:188::-;59121:27;;;;:16;:27;;;;;;;;;59110:38;;;;;;;;;;;;;;;;;59066:26;;59110:38;;;59121:27;59110:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58968:188;;;:::o;59848:493::-;59975:16;59993:21;60054:17;60062:8;60054:7;:17::i;:::-;60032:117;;;;-1:-1:-1;;;60032:117:0;;11157:2:1;60032:117:0;;;11139:21:1;11196:2;11176:18;;;11169:30;11235:34;11215:18;;;11208:62;-1:-1:-1;;;11286:18:1;;;11279:48;11344:19;;60032:117:0;10955:414:1;60032:117:0;60160:18;60181:16;;;:6;:16;;;;;;;;60160:37;;;;;;;;;;;;;;;-1:-1:-1;;;60160:37:0;;;;;;;;;;;-1:-1:-1;;;60160:37:0;;;;;;;;;;;-1:-1:-1;;;60160:37:0;;;;;;;;;;;;;;-1:-1:-1;;;;;60160:37:0;;;;;;;;;;;;60181:16;60160:37;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;60160:37:0;;;;-1:-1:-1;;60221:20:0;;60303:19;;;;-1:-1:-1;;;;;60221:20:0;;;;-1:-1:-1;60160:37:0;;-1:-1:-1;60327:6:0;;60282:41;;-1:-1:-1;60295:28:0;;60282:10;:41;:::i;:::-;60281:52;;;;:::i;:::-;60252:81;;60021:320;59848:493;;;;;:::o;38124:256::-;38221:7;38257:23;38274:5;38257:16;:23::i;:::-;38249:5;:31;38241:87;;;;-1:-1:-1;;;38241:87:0;;12103:2:1;38241:87:0;;;12085:21:1;12142:2;12122:18;;;12115:30;12181:34;12161:18;;;12154:62;-1:-1:-1;;;12232:18:1;;;12225:41;12283:19;;38241:87:0;11901:407:1;38241:87:0;-1:-1:-1;;;;;;38346:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;38124:256::o;54030:53::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;28567:185::-;28705:39;28722:4;28728:2;28732:7;28705:39;;;;;;;;;;;;:16;:39::i;59246:167::-;59318:40;59337:10;59349:8;59318:18;:40::i;:::-;59310:67;;;;-1:-1:-1;;;59310:67:0;;12515:2:1;59310:67:0;;;12497:21:1;12554:2;12534:18;;;12527:30;-1:-1:-1;;;12573:18:1;;;12566:44;12627:18;;59310:67:0;12313:338:1;59310:67:0;59388:15;59394:8;59388:5;:15::i;:::-;59246:167;:::o;55727:234::-;53240:7;;-1:-1:-1;;;;;53240:7:0;53226:10;:21;;:46;;;53265:7;:5;:7::i;:::-;-1:-1:-1;;;;;53251:21:0;:10;-1:-1:-1;;;;;53251:21:0;;53226:46;53218:55;;;;;;-1:-1:-1;;;;;55850:28:0;::::1;55842:63;;;::::0;-1:-1:-1;;;55842:63:0;;12858:2:1;55842:63:0::1;::::0;::::1;12840:21:1::0;12897:2;12877:18;;;12870:30;-1:-1:-1;;;12916:18:1;;;12909:52;12978:18;;55842:63:0::1;12656:346:1::0;55842:63:0::1;55916:20;:37:::0;;-1:-1:-1;;;;;;55916:37:0::1;-1:-1:-1::0;;;;;55916:37:0;;;::::1;::::0;;;::::1;::::0;;55727:234::o;54149:26::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;53881:39::-;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;53881:39:0;;;;;-1:-1:-1;;;53881:39:0;;;;;-1:-1:-1;;;53881:39:0;;;;;;;-1:-1:-1;;;;;53881:39:0;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;38646:233::-;38721:7;38757:30;38544:10;:17;;38456:113;38757:30;38749:5;:38;38741:95;;;;-1:-1:-1;;;38741:95:0;;13209:2:1;38741:95:0;;;13191:21:1;13248:2;13228:18;;;13221:30;13287:34;13267:18;;;13260:62;-1:-1:-1;;;13338:18:1;;;13331:42;13390:19;;38741:95:0;13007:408:1;38741:95:0;38854:10;38865:5;38854:17;;;;;;;;:::i;:::-;;;;;;;;;38847:24;;38646:233;;;:::o;58180:252::-;58266:14;58321:17;58329:8;58321:7;:17::i;:::-;58299:82;;;;-1:-1:-1;;;58299:82:0;;13754:2:1;58299:82:0;;;13736:21:1;13793:2;13773:18;;;13766:30;-1:-1:-1;;;13812:18:1;;;13805:45;13867:18;;58299:82:0;13552:339:1;58299:82:0;-1:-1:-1;58401:16:0;;;;:6;:16;;;;;:23;;;-1:-1:-1;;;;;58401:23:0;;58180:252::o;25402:239::-;25474:7;25510:16;;;:7;:16;;;;;;-1:-1:-1;;;;;25510:16:0;25545:19;25537:73;;;;-1:-1:-1;;;25537:73:0;;14098:2:1;25537:73:0;;;14080:21:1;14137:2;14117:18;;;14110:30;14176:34;14156:18;;;14149:62;-1:-1:-1;;;14227:18:1;;;14220:39;14276:19;;25537:73:0;13896:405:1;58607:188:0;58760:27;;;;:16;:27;;;;;;;;;58749:38;;;;;;;;;;;;;;;;;58705:26;;58749:38;;;58760:27;58749:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58607:188;;;:::o;25132:208::-;25204:7;-1:-1:-1;;;;;25232:19:0;;25224:74;;;;-1:-1:-1;;;25224:74:0;;14508:2:1;25224:74:0;;;14490:21:1;14547:2;14527:18;;;14520:30;14586:34;14566:18;;;14559:62;-1:-1:-1;;;14637:18:1;;;14630:40;14687:19;;25224:74:0;14306:406:1;25224:74:0;-1:-1:-1;;;;;;25316:16:0;;;;;:9;:16;;;;;;;25132:208::o;4558:94::-;2775:10;4127:7;:5;:7::i;:::-;-1:-1:-1;;;;;4127:23:0;;4119:68;;;;-1:-1:-1;;;4119:68:0;;;;;;;:::i;:::-;4623:21:::1;4641:1;4623:9;:21::i;:::-;4558:94::o:0;56676:1338::-;56973:10;;-1:-1:-1;;;56973:10:0;;;;56965:51;;;;-1:-1:-1;;;56965:51:0;;15280:2:1;56965:51:0;;;15262:21:1;15319:2;15299:18;;;15292:30;-1:-1:-1;;;15338:18:1;;;15331:58;15406:18;;56965:51:0;15078:352:1;56965:51:0;57029:19;57104:10;57133:7;57159:9;57187:14;57220;57253:7;57279:8;;57075:227;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;57051:262;;;;;;57029:284;;57348:39;57363:11;57376:2;57380;57384;57348:14;:39::i;:::-;57326:126;;;;-1:-1:-1;;;57326:126:0;;16598:2:1;57326:126:0;;;16580:21:1;16637:2;16617:18;;;16610:30;16676:34;16656:18;;;16649:62;-1:-1:-1;;;16727:18:1;;;16720:35;16772:19;;57326:126:0;16396:401:1;57326:126:0;57465:15;57548:14;57540:23;;57491:9;57483:18;;57517:7;57483:41;;;;:::i;:::-;:80;;;;:::i;:::-;57465:98;;57576:18;57597:165;;;;;;;;57617:7;57597:165;;;;;;57639:9;57597:165;;;;;;57663:14;57597:165;;;;;;57692:14;57597:165;;;;;;57721:7;-1:-1:-1;;;;;57597:165:0;;;;;57743:8;;57597:165;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57597:165:0;;;;-1:-1:-1;;57783:25:0;;;;;;:16;:25;;;;;;;;:39;;;;;;;;;;;;;;;;;;57833:27;;;;;:16;:27;;;;;:41;;;;;;;;;;;;;;;;;57885:15;;;:6;:15;;;;;;:23;;;;;;;;;;;;;;;;;;-1:-1:-1;;;57885:23:0;-1:-1:-1;;;;57885:23:0;;;-1:-1:-1;;;57885:23:0;;;;;-1:-1:-1;;;;;;;;57885:23:0;;;-1:-1:-1;;;57885:23:0;-1:-1:-1;;;;;;57885:23:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57885:23:0;;;-1:-1:-1;;;;;;57885:23:0;;;;;;;;;;;;;;;;57576:186;;-1:-1:-1;57576:186:0;;57885:15;;-1:-1:-1;57885:23:0;;;;;;;;;;:::i;:::-;;;;;57921:27;57931:7;57940;57921:9;:27::i;:::-;57959:47;57973:7;57982:10;57994:7;57959:47;;;;;;;;;;;;:13;:47::i;:::-;56954:1060;;;56676:1338;;;;;;;;;;:::o;3907:87::-;3980:6;;-1:-1:-1;;;;;3980:6:0;;3907:87::o;60440:115::-;53240:7;;-1:-1:-1;;;;;53240:7:0;53226:10;:21;;:46;;;53265:7;:5;:7::i;:::-;-1:-1:-1;;;;;53251:21:0;:10;-1:-1:-1;;;;;53251:21:0;;53226:46;53218:55;;;;;;60524:23;;::::1;::::0;:12:::1;::::0;:23:::1;::::0;::::1;::::0;::::1;:::i;:::-;;60440:115:::0;:::o;61218:145::-;53240:7;;-1:-1:-1;;;;;53240:7:0;53226:10;:21;;:46;;;53265:7;:5;:7::i;:::-;-1:-1:-1;;;;;53251:21:0;:10;-1:-1:-1;;;;;53251:21:0;;53226:46;53218:55;;;;;;61328:27;;::::1;::::0;:12:::1;::::0;:27:::1;::::0;::::1;::::0;::::1;:::i;25877:104::-:0;25933:13;25966:7;25959:14;;;;;:::i;27560:295::-;-1:-1:-1;;;;;27663:24:0;;2775:10;27663:24;;27655:62;;;;-1:-1:-1;;;27655:62:0;;17137:2:1;27655:62:0;;;17119:21:1;17176:2;17156:18;;;17149:30;-1:-1:-1;;;17195:18:1;;;17188:55;17260:18;;27655:62:0;16935:349:1;27655:62:0;2775:10;27730:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;27730:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;27730:53:0;;;;;;;;;;27799:48;;540:41:1;;;27730:42:0;;2775:10;27799:48;;513:18:1;27799:48:0;;;;;;;27560:295;;:::o;53947:53::-;;;;;;;;;;;;;;;;;;;;28823:328;28998:41;2775:10;29031:7;28998:18;:41::i;:::-;28990:103;;;;-1:-1:-1;;;28990:103:0;;;;;;;:::i;:::-;29104:39;29118:4;29124:2;29128:7;29137:5;29104:13;:39::i;:::-;28823:328;;;;:::o;60773:396::-;60892:13;60945:17;60953:8;60945:7;:17::i;:::-;60923:114;;;;-1:-1:-1;;;60923:114:0;;17491:2:1;60923:114:0;;;17473:21:1;17530:2;17510:18;;;17503:30;17569:34;17549:18;;;17542:62;-1:-1:-1;;;17620:18:1;;;17613:45;17675:19;;60923:114:0;17289:411:1;60923:114:0;61050:20;61073:16;;;:6;:16;;;;;:24;;61050:47;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61141:10;:8;:10::i;:::-;61153:6;61124:36;;;;;;;;;:::i;:::-;;;;;;;;;;;;;61110:51;;;60773:396;;;:::o;53301:145::-;2775:10;4127:7;:5;:7::i;:::-;-1:-1:-1;;;;;4127:23:0;;4119:68;;;;-1:-1:-1;;;4119:68:0;;;;;;;:::i;:::-;53372:7:::1;:21:::0;;-1:-1:-1;;;;;;53372:21:0::1;-1:-1:-1::0;;;;;53372:21:0;::::1;;::::0;;53411:27:::1;::::0;::::1;::::0;::::1;::::0;53372:21;;53411:27:::1;:::i;:::-;;;;;;;;53301:145:::0;:::o;61436:99::-;61482:13;61515:12;61508:19;;;;;:::i;27926:164::-;-1:-1:-1;;;;;28047:25:0;;;28023:4;28047:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;27926:164::o;4807:192::-;2775:10;4127:7;:5;:7::i;:::-;-1:-1:-1;;;;;4127:23:0;;4119:68;;;;-1:-1:-1;;;4119:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;4896:22:0;::::1;4888:73;;;::::0;-1:-1:-1;;;4888:73:0;;18382:2:1;4888:73:0::1;::::0;::::1;18364:21:1::0;18421:2;18401:18;;;18394:30;18460:34;18440:18;;;18433:62;-1:-1:-1;;;18511:18:1;;;18504:36;18557:19;;4888:73:0::1;18180:402:1::0;4888:73:0::1;4972:19;4982:8;4972:9;:19::i;24763:305::-:0;24865:4;-1:-1:-1;;;;;;24902:40:0;;-1:-1:-1;;;24902:40:0;;:105;;-1:-1:-1;;;;;;;24959:48:0;;-1:-1:-1;;;24959:48:0;24902:105;:158;;;-1:-1:-1;;;;;;;;;;16851:40:0;;;25024:36;16742:157;30661:127;30726:4;30750:16;;;:7;:16;;;;;;-1:-1:-1;;;;;30750:16:0;:30;;;30661:127::o;34643:174::-;34718:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;34718:29:0;-1:-1:-1;;;;;34718:29:0;;;;;;;;:24;;34772:23;34718:24;34772:14;:23::i;:::-;-1:-1:-1;;;;;34763:46:0;;;;;;;;;;;34643:174;;:::o;30955:348::-;31048:4;31073:16;31081:7;31073;:16::i;:::-;31065:73;;;;-1:-1:-1;;;31065:73:0;;18789:2:1;31065:73:0;;;18771:21:1;18828:2;18808:18;;;18801:30;18867:34;18847:18;;;18840:62;-1:-1:-1;;;18918:18:1;;;18911:42;18970:19;;31065:73:0;18587:408:1;31065:73:0;31149:13;31165:23;31180:7;31165:14;:23::i;:::-;31149:39;;31218:5;-1:-1:-1;;;;;31207:16:0;:7;-1:-1:-1;;;;;31207:16:0;;:51;;;;31251:7;-1:-1:-1;;;;;31227:31:0;:20;31239:7;31227:11;:20::i;:::-;-1:-1:-1;;;;;31227:31:0;;31207:51;:87;;;;31262:32;31279:5;31286:7;31262:16;:32::i;:::-;31199:96;30955:348;-1:-1:-1;;;;30955:348:0:o;33947:578::-;34106:4;-1:-1:-1;;;;;34079:31:0;:23;34094:7;34079:14;:23::i;:::-;-1:-1:-1;;;;;34079:31:0;;34071:85;;;;-1:-1:-1;;;34071:85:0;;19202:2:1;34071:85:0;;;19184:21:1;19241:2;19221:18;;;19214:30;19280:34;19260:18;;;19253:62;-1:-1:-1;;;19331:18:1;;;19324:39;19380:19;;34071:85:0;19000:405:1;34071:85:0;-1:-1:-1;;;;;34175:16:0;;34167:65;;;;-1:-1:-1;;;34167:65:0;;19612:2:1;34167:65:0;;;19594:21:1;19651:2;19631:18;;;19624:30;19690:34;19670:18;;;19663:62;-1:-1:-1;;;19741:18:1;;;19734:34;19785:19;;34167:65:0;19410:400:1;34167:65:0;34245:39;34266:4;34272:2;34276:7;34245:20;:39::i;:::-;34349:29;34366:1;34370:7;34349:8;:29::i;:::-;-1:-1:-1;;;;;34391:15:0;;;;;;:9;:15;;;;;:20;;34410:1;;34391:15;:20;;34410:1;;34391:20;:::i;:::-;;;;-1:-1:-1;;;;;;;34422:13:0;;;;;;:9;:13;;;;;:18;;34439:1;;34422:13;:18;;34439:1;;34422:18;:::i;:::-;;;;-1:-1:-1;;34451:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;34451:21:0;-1:-1:-1;;;;;34451:21:0;;;;;;;;;34490:27;;34451:16;;34490:27;;;;-1:-1:-1;;;;;;;;;;;34490:27:0;;33947:578;;;:::o;33250:360::-;33310:13;33326:23;33341:7;33326:14;:23::i;:::-;33310:39;;33362:48;33383:5;33398:1;33402:7;33362:20;:48::i;:::-;33451:29;33468:1;33472:7;33451:8;:29::i;:::-;-1:-1:-1;;;;;33493:16:0;;;;;;:9;:16;;;;;:21;;33513:1;;33493:16;:21;;33513:1;;33493:21;:::i;:::-;;;;-1:-1:-1;;33532:16:0;;;;:7;:16;;;;;;33525:23;;-1:-1:-1;;;;;;33525:23:0;;;33566:36;33540:7;;33532:16;-1:-1:-1;;;;;33566:36:0;;;-1:-1:-1;;;;;;;;;;;33566:36:0;33532:16;;33566:36;33299:311;33250:360;:::o;5007:173::-;5082:6;;;-1:-1:-1;;;;;5099:17:0;;;-1:-1:-1;;;;;;5099:17:0;;;;;;;5132:40;;5082:6;;;5099:17;5082:6;;5132:40;;5063:16;;5132:40;5052:128;5007:173;:::o;55112:385::-;55254:15;55282:14;55299:128;55327:38;55356:8;52350:58;;-1:-1:-1;;;52350:58:0;;;20594:80:1;20690:12;;;20683:28;;;52217:7:0;;20727:12:1;;52350:58:0;;;;;;;;;;;;52340:69;;;;;;52333:76;;52148:269;;;;55327:38;55380:2;55397;55414;55299:13;:128::i;:::-;55461:7;;55282:145;;-1:-1:-1;;;;;;55451:17:0;;;55461:7;;55451:17;;:38;;;55482:7;:5;:7::i;:::-;-1:-1:-1;;;;;55472:17:0;:6;-1:-1:-1;;;;;55472:17:0;;55451:38;55438:51;55112:385;-1:-1:-1;;;;;;55112:385:0:o;31645:110::-;31721:26;31731:2;31735:7;31721:26;;;;;;;;;;;;:9;:26::i;30033:315::-;30190:28;30200:4;30206:2;30210:7;30190:9;:28::i;:::-;30237:48;30260:4;30266:2;30270:7;30279:5;30237:22;:48::i;:::-;30229:111;;;;-1:-1:-1;;;30229:111:0;;;;;;;:::i;60567:113::-;60627:13;60660:12;60653:19;;;;;:::i;39492:589::-;-1:-1:-1;;;;;39698:18:0;;39694:187;;39733:40;39765:7;40908:10;:17;;40881:24;;;;:15;:24;;;;;:44;;;40936:24;;;;;;;;;;;;40804:164;39733:40;39694:187;;;39803:2;-1:-1:-1;;;;;39795:10:0;:4;-1:-1:-1;;;;;39795:10:0;;39791:90;;39822:47;39855:4;39861:7;39822:32;:47::i;:::-;-1:-1:-1;;;;;39895:16:0;;39891:183;;39928:45;39965:7;39928:36;:45::i;39891:183::-;40001:4;-1:-1:-1;;;;;39995:10:0;:2;-1:-1:-1;;;;;39995:10:0;;39991:83;;40022:40;40050:2;40054:7;40022:27;:40::i;51569:279::-;51697:7;51718:17;51737:18;51759:25;51770:4;51776:1;51779;51782;51759:10;:25::i;:::-;51717:67;;;;51795:18;51807:5;51795:11;:18::i;:::-;-1:-1:-1;51831:9:0;51569:279;-1:-1:-1;;;;;51569:279:0:o;31982:321::-;32112:18;32118:2;32122:7;32112:5;:18::i;:::-;32163:54;32194:1;32198:2;32202:7;32211:5;32163:22;:54::i;:::-;32141:154;;;;-1:-1:-1;;;32141:154:0;;;;;;;:::i;35382:799::-;35537:4;-1:-1:-1;;;;;35558:13:0;;6276:20;6324:8;35554:620;;35594:72;;-1:-1:-1;;;35594:72:0;;-1:-1:-1;;;;;35594:36:0;;;;;:72;;2775:10;;35645:4;;35651:7;;35660:5;;35594:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35594:72:0;;;;;;;;-1:-1:-1;;35594:72:0;;;;;;;;;;;;:::i;:::-;;;35590:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35836:13:0;;35832:272;;35879:60;;-1:-1:-1;;;35879:60:0;;;;;;;:::i;35832:272::-;36054:6;36048:13;36039:6;36035:2;36031:15;36024:38;35590:529;-1:-1:-1;;;;;;35717:51:0;-1:-1:-1;;;35717:51:0;;-1:-1:-1;35710:58:0;;35554:620;-1:-1:-1;36158:4:0;36151:11;;41595:988;41861:22;41911:1;41886:22;41903:4;41886:16;:22::i;:::-;:26;;;;:::i;:::-;41923:18;41944:26;;;:17;:26;;;;;;41861:51;;-1:-1:-1;42077:28:0;;;42073:328;;-1:-1:-1;;;;;42144:18:0;;42122:19;42144:18;;;:12;:18;;;;;;;;:34;;;;;;;;;42195:30;;;;;;:44;;;42312:30;;:17;:30;;;;;:43;;;42073:328;-1:-1:-1;42497:26:0;;;;:17;:26;;;;;;;;42490:33;;;-1:-1:-1;;;;;42541:18:0;;;;;:12;:18;;;;;:34;;;;;;;42534:41;41595:988::o;42878:1079::-;43156:10;:17;43131:22;;43156:21;;43176:1;;43156:21;:::i;:::-;43188:18;43209:24;;;:15;:24;;;;;;43582:10;:26;;43131:46;;-1:-1:-1;43209:24:0;;43131:46;;43582:26;;;;;;:::i;:::-;;;;;;;;;43560:48;;43646:11;43621:10;43632;43621:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;43726:28;;;:15;:28;;;;;;;:41;;;43898:24;;;;;43891:31;43933:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;42949:1008;;;42878:1079;:::o;40382:221::-;40467:14;40484:20;40501:2;40484:16;:20::i;:::-;-1:-1:-1;;;;;40515:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;40560:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;40382:221:0:o;49798:1632::-;49929:7;;-1:-1:-1;;;;;50850:79:0;;50846:163;;;-1:-1:-1;50962:1:0;;-1:-1:-1;50966:30:0;50946:51;;50846:163;51023:1;:7;;51028:2;51023:7;;:18;;;;;51034:1;:7;;51039:2;51034:7;;51023:18;51019:102;;;-1:-1:-1;51074:1:0;;-1:-1:-1;51078:30:0;51058:51;;51019:102;51235:24;;;51218:14;51235:24;;;;;;;;;21857:25:1;;;21930:4;21918:17;;21898:18;;;21891:45;;;;21952:18;;;21945:34;;;21995:18;;;21988:34;;;51235:24:0;;21829:19:1;;51235:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;51235:24:0;;-1:-1:-1;;51235:24:0;;;-1:-1:-1;;;;;;;51274:20:0;;51270:103;;51327:1;51331:29;51311:50;;;;;;;51270:103;51393:6;-1:-1:-1;51401:20:0;;-1:-1:-1;49798:1632:0;;;;;;;;:::o;44460:643::-;44538:20;44529:5;:29;;;;;;;;:::i;:::-;;44525:571;;;44460:643;:::o;44525:571::-;44636:29;44627:5;:38;;;;;;;;:::i;:::-;;44623:473;;;44682:34;;-1:-1:-1;;;44682:34:0;;22367:2:1;44682:34:0;;;22349:21:1;22406:2;22386:18;;;22379:30;-1:-1:-1;;;22425:18:1;;;22418:54;22489:18;;44682:34:0;22165:348:1;44623:473:0;44747:35;44738:5;:44;;;;;;;;:::i;:::-;;44734:362;;;44799:41;;-1:-1:-1;;;44799:41:0;;22720:2:1;44799:41:0;;;22702:21:1;22759:2;22739:18;;;22732:30;22798:33;22778:18;;;22771:61;22849:18;;44799:41:0;22518:355:1;44734:362:0;44871:30;44862:5;:39;;;;;;;;:::i;:::-;;44858:238;;;44918:44;;-1:-1:-1;;;44918:44:0;;23080:2:1;44918:44:0;;;23062:21:1;23119:2;23099:18;;;23092:30;23158:34;23138:18;;;23131:62;-1:-1:-1;;;23209:18:1;;;23202:32;23251:19;;44918:44:0;22878:398:1;44858:238:0;44993:30;44984:5;:39;;;;;;;;:::i;:::-;;44980:116;;;45040:44;;-1:-1:-1;;;45040:44:0;;23483:2:1;45040:44:0;;;23465:21:1;23522:2;23502:18;;;23495:30;23561:34;23541:18;;;23534:62;-1:-1:-1;;;23612:18:1;;;23605:32;23654:19;;45040:44:0;23281:398:1;32639:382:0;-1:-1:-1;;;;;32719:16:0;;32711:61;;;;-1:-1:-1;;;32711:61:0;;23886:2:1;32711:61:0;;;23868:21:1;;;23905:18;;;23898:30;23964:34;23944:18;;;23937:62;24016:18;;32711:61:0;23684:356:1;32711:61:0;32792:16;32800:7;32792;:16::i;:::-;32791:17;32783:58;;;;-1:-1:-1;;;32783:58:0;;24247:2:1;32783:58:0;;;24229:21:1;24286:2;24266:18;;;24259:30;-1:-1:-1;;;24305:18:1;;;24298:58;24373:18;;32783:58:0;24045:352:1;32783:58:0;32854:45;32883:1;32887:2;32891:7;32854:20;:45::i;:::-;-1:-1:-1;;;;;32912:13:0;;;;;;:9;:13;;;;;:18;;32929:1;;32912:13;:18;;32929:1;;32912:18;:::i;:::-;;;;-1:-1:-1;;32941:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;32941:21:0;-1:-1:-1;;;;;32941:21:0;;;;;;;;32980:33;;32941:16;;;-1:-1:-1;;;;;;;;;;;32980:33:0;32941:16;;32980:33;32639:382;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;:::-;384:5;150:245;-1:-1:-1;;;150:245:1:o;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:1;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:1:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:180::-;1402:6;1455:2;1443:9;1434:7;1430:23;1426:32;1423:52;;;1471:1;1468;1461:12;1423:52;-1:-1:-1;1494:23:1;;1343:180;-1:-1:-1;1343:180:1:o;1528:203::-;-1:-1:-1;;;;;1692:32:1;;;;1674:51;;1662:2;1647:18;;1528:203::o;1736:173::-;1804:20;;-1:-1:-1;;;;;1853:31:1;;1843:42;;1833:70;;1899:1;1896;1889:12;1833:70;1736:173;;;:::o;1914:254::-;1982:6;1990;2043:2;2031:9;2022:7;2018:23;2014:32;2011:52;;;2059:1;2056;2049:12;2011:52;2082:29;2101:9;2082:29;:::i;:::-;2072:39;2158:2;2143:18;;;;2130:32;;-1:-1:-1;;;1914:254:1:o;2355:328::-;2432:6;2440;2448;2501:2;2489:9;2480:7;2476:23;2472:32;2469:52;;;2517:1;2514;2507:12;2469:52;2540:29;2559:9;2540:29;:::i;:::-;2530:39;;2588:38;2622:2;2611:9;2607:18;2588:38;:::i;:::-;2578:48;;2673:2;2662:9;2658:18;2645:32;2635:42;;2355:328;;;;;:::o;2688:160::-;2753:20;;2809:13;;2802:21;2792:32;;2782:60;;2838:1;2835;2828:12;2853:180;2909:6;2962:2;2950:9;2941:7;2937:23;2933:32;2930:52;;;2978:1;2975;2968:12;2930:52;3001:26;3017:9;3001:26;:::i;3038:632::-;3209:2;3261:21;;;3331:13;;3234:18;;;3353:22;;;3180:4;;3209:2;3432:15;;;;3406:2;3391:18;;;3180:4;3475:169;3489:6;3486:1;3483:13;3475:169;;;3550:13;;3538:26;;3619:15;;;;3584:12;;;;3511:1;3504:9;3475:169;;;-1:-1:-1;3661:3:1;;3038:632;-1:-1:-1;;;;;;3038:632:1:o;3675:248::-;3743:6;3751;3804:2;3792:9;3783:7;3779:23;3775:32;3772:52;;;3820:1;3817;3810:12;3772:52;-1:-1:-1;;3843:23:1;;;3913:2;3898:18;;;3885:32;;-1:-1:-1;3675:248:1:o;4207:186::-;4266:6;4319:2;4307:9;4298:7;4294:23;4290:32;4287:52;;;4335:1;4332;4325:12;4287:52;4358:29;4377:9;4358:29;:::i;4398:662::-;4671:10;4708:15;;;4690:34;;4760:15;;;4755:2;4740:18;;4733:43;4812:15;;;4807:2;4792:18;;4785:43;4864:15;;4859:2;4844:18;;4837:43;-1:-1:-1;;;;;4917:32:1;;4911:3;4896:19;;4889:61;4987:3;4937;4966:19;;4959:32;;;4642:4;;5008:46;;5034:19;;5026:6;5008:46;:::i;:::-;5000:54;4398:662;-1:-1:-1;;;;;;;;4398:662:1:o;5065:163::-;5132:20;;5192:10;5181:22;;5171:33;;5161:61;;5218:1;5215;5208:12;5233:1253;5370:6;5378;5386;5394;5402;5410;5418;5426;5434;5442;5495:3;5483:9;5474:7;5470:23;5466:33;5463:53;;;5512:1;5509;5502:12;5463:53;5548:9;5535:23;5525:33;;5605:2;5594:9;5590:18;5577:32;5567:42;;5659:2;5648:9;5644:18;5631:32;5703:4;5696:5;5692:16;5685:5;5682:27;5672:55;;5723:1;5720;5713:12;5672:55;5746:5;-1:-1:-1;5770:37:1;5803:2;5788:18;;5770:37;:::i;:::-;5760:47;;5826:38;5859:3;5848:9;5844:19;5826:38;:::i;:::-;5816:48;;5883:38;5916:3;5905:9;5901:19;5883:38;:::i;:::-;5873:48;;5940:38;5973:3;5962:9;5958:19;5940:38;:::i;:::-;5930:48;;5997:39;6031:3;6020:9;6016:19;5997:39;:::i;:::-;5987:49;-1:-1:-1;6087:3:1;6072:19;;6059:33;-1:-1:-1;;;;;6141:14:1;;;6138:34;;;6168:1;6165;6158:12;6138:34;6206:6;6195:9;6191:22;6181:32;;6251:7;6244:4;6240:2;6236:13;6232:27;6222:55;;6273:1;6270;6263:12;6222:55;6313:2;6300:16;6339:2;6331:6;6328:14;6325:34;;;6355:1;6352;6345:12;6325:34;6400:7;6395:2;6386:6;6382:2;6378:15;6374:24;6371:37;6368:57;;;6421:1;6418;6411:12;6368:57;6452:2;6448;6444:11;6434:21;;6474:6;6464:16;;;;;5233:1253;;;;;;;;;;;;;:::o;6491:127::-;6552:10;6547:3;6543:20;6540:1;6533:31;6583:4;6580:1;6573:15;6607:4;6604:1;6597:15;6623:632;6688:5;-1:-1:-1;;;;;6748:14:1;;;6745:40;;;6765:18;;:::i;:::-;6840:2;6834:9;6808:2;6894:15;;-1:-1:-1;;6890:24:1;;;6916:2;6886:33;6882:42;6870:55;;;6940:18;;;6960:22;;;6937:46;6934:72;;;6986:18;;:::i;:::-;7026:10;7022:2;7015:22;7055:6;7046:15;;7085:6;7077;7070:22;7125:3;7116:6;7111:3;7107:16;7104:25;7101:45;;;7142:1;7139;7132:12;7101:45;7192:6;7187:3;7180:4;7172:6;7168:17;7155:44;7247:1;7240:4;7231:6;7223;7219:19;7215:30;7208:41;;;;6623:632;;;;;:::o;7260:451::-;7329:6;7382:2;7370:9;7361:7;7357:23;7353:32;7350:52;;;7398:1;7395;7388:12;7350:52;7425:23;;-1:-1:-1;;;;;7460:30:1;;7457:50;;;7503:1;7500;7493:12;7457:50;7526:22;;7579:4;7571:13;;7567:27;-1:-1:-1;7557:55:1;;7608:1;7605;7598:12;7557:55;7631:74;7697:7;7692:2;7679:16;7674:2;7670;7666:11;7631:74;:::i;7716:254::-;7781:6;7789;7842:2;7830:9;7821:7;7817:23;7813:32;7810:52;;;7858:1;7855;7848:12;7810:52;7881:29;7900:9;7881:29;:::i;:::-;7871:39;;7929:35;7960:2;7949:9;7945:18;7929:35;:::i;:::-;7919:45;;7716:254;;;;;:::o;7975:667::-;8070:6;8078;8086;8094;8147:3;8135:9;8126:7;8122:23;8118:33;8115:53;;;8164:1;8161;8154:12;8115:53;8187:29;8206:9;8187:29;:::i;:::-;8177:39;;8235:38;8269:2;8258:9;8254:18;8235:38;:::i;:::-;8225:48;-1:-1:-1;8320:2:1;8305:18;;8292:32;;-1:-1:-1;8375:2:1;8360:18;;8347:32;-1:-1:-1;;;;;8391:30:1;;8388:50;;;8434:1;8431;8424:12;8388:50;8457:22;;8510:4;8502:13;;8498:27;-1:-1:-1;8488:55:1;;8539:1;8536;8529:12;8488:55;8562:74;8628:7;8623:2;8610:16;8605:2;8601;8597:11;8562:74;:::i;:::-;8552:84;;;7975:667;;;;;;;:::o;8647:260::-;8715:6;8723;8776:2;8764:9;8755:7;8751:23;8747:32;8744:52;;;8792:1;8789;8782:12;8744:52;8815:29;8834:9;8815:29;:::i;:::-;8805:39;;8863:38;8897:2;8886:9;8882:18;8863:38;:::i;8912:380::-;8991:1;8987:12;;;;9034;;;9055:61;;9109:4;9101:6;9097:17;9087:27;;9055:61;9162:2;9154:6;9151:14;9131:18;9128:38;9125:161;;;9208:10;9203:3;9199:20;9196:1;9189:31;9243:4;9240:1;9233:15;9271:4;9268:1;9261:15;9125:161;;8912:380;;;:::o;10537:413::-;10739:2;10721:21;;;10778:2;10758:18;;;10751:30;10817:34;10812:2;10797:18;;10790:62;-1:-1:-1;;;10883:2:1;10868:18;;10861:47;10940:3;10925:19;;10537:413::o;11374:127::-;11435:10;11430:3;11426:20;11423:1;11416:31;11466:4;11463:1;11456:15;11490:4;11487:1;11480:15;11506:168;11546:7;11612:1;11608;11604:6;11600:14;11597:1;11594:21;11589:1;11582:9;11575:17;11571:45;11568:71;;;11619:18;;:::i;:::-;-1:-1:-1;11659:9:1;;11506:168::o;11679:217::-;11719:1;11745;11735:132;;11789:10;11784:3;11780:20;11777:1;11770:31;11824:4;11821:1;11814:15;11852:4;11849:1;11842:15;11735:132;-1:-1:-1;11881:9:1;;11679:217::o;13420:127::-;13481:10;13476:3;13472:20;13469:1;13462:31;13512:4;13509:1;13502:15;13536:4;13533:1;13526:15;14717:356;14919:2;14901:21;;;14938:18;;;14931:30;14997:34;14992:2;14977:18;;14970:62;15064:2;15049:18;;14717:356::o;15435:956::-;-1:-1:-1;;;;;15792:15:1;;;15774:34;;15827:10;15873:15;;;15868:2;15853:18;;15846:43;15925:15;;;15920:2;15905:18;;15898:43;15977:15;;;15972:2;15957:18;;15950:43;16030:15;;16024:3;16009:19;;16002:44;16083:15;;15754:3;16062:19;;16055:44;16136:3;16130;16115:19;;16108:32;;;16156:19;;16149:35;;;15717:4;16203:3;16177:6;16248;16228:18;;;16215:48;16312:1;16283:22;;;16279:31;;16272:42;16375:2;16354:15;;;-1:-1:-1;;16350:29:1;16335:45;;;16331:54;;;;15435:956;-1:-1:-1;;;;;;;;15435:956:1:o;16802:128::-;16842:3;16873:1;16869:6;16866:1;16863:13;16860:39;;;16879:18;;:::i;:::-;-1:-1:-1;16915:9:1;;16802:128::o;17705:470::-;17884:3;17922:6;17916:13;17938:53;17984:6;17979:3;17972:4;17964:6;17960:17;17938:53;:::i;:::-;18054:13;;18013:16;;;;18076:57;18054:13;18013:16;18110:4;18098:17;;18076:57;:::i;:::-;18149:20;;17705:470;-1:-1:-1;;;;17705:470:1:o;19815:125::-;19855:4;19883:1;19880;19877:8;19874:34;;;19888:18;;:::i;:::-;-1:-1:-1;19925:9:1;;19815:125::o;19945:414::-;20147:2;20129:21;;;20186:2;20166:18;;;20159:30;20225:34;20220:2;20205:18;;20198:62;-1:-1:-1;;;20291:2:1;20276:18;;20269:48;20349:3;20334:19;;19945:414::o;20750:489::-;-1:-1:-1;;;;;21019:15:1;;;21001:34;;21071:15;;21066:2;21051:18;;21044:43;21118:2;21103:18;;21096:34;;;21166:3;21161:2;21146:18;;21139:31;;;20944:4;;21187:46;;21213:19;;21205:6;21187:46;:::i;21244:249::-;21313:6;21366:2;21354:9;21345:7;21341:23;21337:32;21334:52;;;21382:1;21379;21372:12;21334:52;21414:9;21408:16;21433:30;21457:5;21433:30;:::i;21498:127::-;21559:10;21554:3;21550:20;21547:1;21540:31;21590:4;21587:1;21580:15;21614:4;21611:1;21604:15;22033:127;22094:10;22089:3;22085:20;22082:1;22075:31;22125:4;22122:1;22115:15;22149:4;22146:1;22139:15

Swarm Source

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