Feature Tip: Add private address tag to any address under My Name Tag !
Overview
Max Total Supply
1,024 CPHR
Holders
497
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 CPHRLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Cypher
Compiler Version
v0.8.6+commit.11564f7e
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-11-09 */ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.0 <0.9.0; // =============================================== // TERMS AND CONDITIONS // https://www.anma.io/legal // =============================================== /* HIDEKI TSUKAMOTO | ANOMALOUS MATERIALS | 15.08.2021 ______________.___.__________ ___ _______________________ \_ ___ \__ | |\______ \/ | \_ _____|______ \ / \ \// | | | ___/ ~ \ __)_ | _/ \ \___\____ | | | \ Y / \| | \ \______ / ______| |____| \___|_ /_______ /|____|_ / \/\/ \/ \/ \/ */ /* * @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; } } /** * @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); } } /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } /** * @dev Required interface of an 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; } /** * @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; } } /** * @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); } /** * @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); } /** * @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); } function _verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) private 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); } } } } /** * @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); } } /** * @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(to).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 {} } /** * @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); } /** * @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(); } } struct CypherAttributes { uint colorset; int decay; int chaos; int utilRand; int numChannels; int[8] density; int[8] intricacy; } struct StringBuilder { bytes data; } library SB { function create(uint256 capacity) internal pure returns(StringBuilder memory) { return StringBuilder(new bytes(capacity + 32)); } function resize(StringBuilder memory sb, uint256 newCapacity) internal view { StringBuilder memory newSb = create(newCapacity); assembly { let data := mload(sb) let newData := mload(newSb) let size := mload(add(data, 32)) // get used byte count let bytesToCopy := add(size, 32) // copy the used bytes, plus the size field in first 32 bytes pop(staticcall( gas(), 0x4, add(data, 32), bytesToCopy, add(newData, 32), bytesToCopy)) } sb.data = newSb.data; } function resizeIfNeeded(StringBuilder memory sb, uint256 spaceNeeded) internal view { uint capacity; uint size; assembly { let data := mload(sb) capacity := sub(mload(data), 32) size := mload(add(data, 32)) } uint remaining = capacity - size; if (remaining >= spaceNeeded) { return; } uint newCapacity = capacity << 1; uint newRemaining = newCapacity - size; if (newRemaining >= spaceNeeded) { resize(sb, newCapacity); } else { newCapacity = spaceNeeded + size; resize(sb, newCapacity); } } function getString(StringBuilder memory sb) internal pure returns(string memory) { string memory ret; assembly { let data := mload(sb) ret := add(data, 32) } return ret; } function writeStr(StringBuilder memory sb, string memory str) internal view { resizeIfNeeded(sb, bytes(str).length); assembly { let data := mload(sb) let size := mload(add(data, 32)) pop(staticcall(gas(), 0x4, add(str, 32), mload(str), add(size, add(data, 64)), mload(str))) mstore(add(data, 32), add(size, mload(str))) } } function concat(StringBuilder memory dst, StringBuilder memory src) internal view { string memory asString; assembly { let srcData := mload(src) asString := add(srcData, 32) } writeStr(dst, asString); } function writeUint(StringBuilder memory sb, uint u) internal view { if (u > 0) { uint len; uint size; assembly { // get length string will be len := 0 for {let val := u} gt(val, 0) {val := div(val, 10) len := add(len, 1)} { } // get bytes currently used let data := mload(sb) size := mload(add(data, 32)) } // make sure there's room resizeIfNeeded(sb, len); assembly { let data := mload(sb) for {let i := 0 let val := u} lt(i, len) {i := add(i, 1) val := div(val, 10)} { // sb.data[64 + size + (len - i - 1)] = (val % 10) + 48 mstore8(add(data, add(63, add(size, sub(len, i)))), add(mod(val, 10), 48)) } size := add(size, len) mstore(add(data, 32), size) } } else { uint size; assembly { let data := mload(sb) size := mload(add(data, 32)) } // make sure there's room resizeIfNeeded(sb, 1); assembly { let data := mload(sb) mstore(add(data, 32), add(size, 1)) mstore8(add(data, add(64, size)), 48) } } } function writeInt(StringBuilder memory sb, int i) internal view { if (i < 0) { // write the - sign uint size; assembly { let data := mload(sb) size := mload(add(data, 32)) } resizeIfNeeded(sb, 1); assembly { let data := mload(sb) mstore(add(data, 32), add(size, 1)) mstore8(add(data, add(64, size)), 45) } // now the digits can be written as a uint i *= -1; } writeUint(sb, uint(i)); } function writeRgb(StringBuilder memory sb, uint256 col) internal view { resizeIfNeeded(sb, 6); string[16] memory nibbles = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"]; string memory asStr = string(abi.encodePacked( nibbles[(col >> 20) & 0xf], nibbles[(col >> 16) & 0xf], nibbles[(col >> 12) & 0xf], nibbles[(col >> 8) & 0xf], nibbles[(col >> 4) & 0xf], nibbles[col & 0xf] )); writeStr(sb, asStr); } } struct Rand { uint256 value; } library Random { function create(uint256 srand) internal pure returns(Rand memory) { Rand memory rand = Rand({value: srand}); return rand; } function value(Rand memory rand) internal pure returns(uint256) { rand.value = uint256(keccak256(abi.encodePacked(rand.value))); return rand.value; } // (max inclusive) function range(Rand memory rand, int256 min, int256 max) internal pure returns(int256) { if (min <= max) { uint256 span = uint256(max - min); return int256(value(rand) % (span + 1)) + min; } else { return range(rand, max, min); } } } contract CypherDrawing is Ownable { int constant FONT_SIZE = 4; uint8[1024] private curve; int8[1024] private noiseTable; uint24[256][5] private gradients; function setCurve(uint8[1024] memory newCurve) public onlyOwner { curve = newCurve; } function setNoiseTable(int8[1024] memory newNoiseTable) public onlyOwner { noiseTable = newNoiseTable; } function setGradients(uint24[256][5] memory newGradients) public onlyOwner { gradients = newGradients; } function getAttributes(bytes32 hash) public view returns (CypherAttributes memory) { Rand memory rand = Random.create(uint256(hash)); CypherAttributes memory attributes = createAttributes(rand); return attributes; } function generate(bytes32 hash) public view returns(string memory) { StringBuilder memory b = SB.create(128 * 1024); SB.writeStr(b, "<svg viewBox='0 0 640 640' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>" "<style>" "text{" "font-size:"); SB.writeInt(b, FONT_SIZE); SB.writeStr(b, "px;" "font-family: monospace;" "fill: #cccccc;" "}" "</style>" "<defs>" "<filter id='glow'>" "<feGaussianBlur stdDeviation='3.0' result='coloredBlur'/>" "<feComponentTransfer in='coloredBlur' result='coloredBlur'>" "<feFuncA type='linear' slope='0.70'/>" "</feComponentTransfer>" "<feMerge>" "<feMergeNode in='coloredBlur'/>" "<feMergeNode in='SourceGraphic'/>" "</feMerge>" "</filter>" "</defs>" "<rect width='640' height='640' fill='#090809'/>" "<g id='cypher' shape-rendering='geometricPrecision' filter='url(#glow)'>"); Rand memory rand = Random.create(uint256(hash)); CypherAttributes memory attributes = createAttributes(rand); draw(b, attributes, rand); SB.writeStr(b, "</g>" "</svg>"); return SB.getString(b); } struct Ring { uint id; int arcs; int span; int inner; int outer; } struct SegmentData { uint ringId; uint segId; int inner; int outer; int thick; int start; int fin; EdgeType edge; FillType fill; SpanType innerSpanType; PadType padInner; SpanType outerSpanType; PadType padOuter; uint colour; } enum SpanType { None, Arc, Cap, Ang, Brk, Dotted } enum Variant { None, Inner, Outer, Double, Max } enum EdgeType { None, Simple } enum FillType { None, Block, Hollow, Text, Increment, Comp } enum PadType { None, Single } function clamp(int num) private pure returns(int) { return clamp(num, 0, 31); } function clamp(int num, int min, int max) private pure returns(int) { return num <= min ? min : num >= max ? max : num; } function noise(Rand memory rand) private view returns(int) { return noiseTable[uint(Random.range(rand, 0, 1023))]; } function createAttributes(Rand memory rand) private view returns(CypherAttributes memory) { int weighted = int8(curve[uint(Random.range(rand, 0, 1023))]); CypherAttributes memory attributes; attributes.colorset = (uint(weighted < int(8) ? int(8) : weighted) - 8)/6; attributes.decay = 32 - clamp(weighted + noise(rand)); attributes.chaos = 32 - clamp(weighted + noise(rand)); attributes.utilRand = Random.range(rand, 0, 1023); attributes.numChannels = 4 + (clamp(weighted + noise(rand), 0, 32) >> 3); int count = 0; while(true) { uint idx = uint(Random.range(rand, 0, 7)); if(count == attributes.numChannels) { break; } else if(attributes.density[idx]==1) { continue; } else { attributes.density[idx]=1; count++; } } for (uint i = 0; i < 8; ++i) { attributes.intricacy[i] = clamp(weighted + noise(rand)); } return attributes; } function getSegmentColour( CypherAttributes memory atr, Ring memory ring, Rand memory rand) private view returns(uint24) { int array_offset = atr.utilRand % 256; int grad_noise = Random.range(rand, 0, 30); int colour_index = (array_offset + ring.inner + grad_noise) % 256; return gradients[atr.colorset][uint(colour_index)]; } function draw( StringBuilder memory b, CypherAttributes memory atr, Rand memory rand) private view { Ring[16] memory rings = createRings(rand); // frame for(uint i=0; i<16; ++i) { SB.writeStr(b, "<circle cx='320' cy='320' fill='none' stroke-width='0.1' stroke-opacity='15%' stroke='#"); SB.writeRgb(b, gradients[atr.colorset][uint(rings[i].inner)-1]); SB.writeStr(b, "' r='"); SB.writeInt(b, rings[i].inner); SB.writeStr(b, "'/>"); } // defs & ring // defs added as we go, ring must be deferred SB.writeStr(b, "<defs>"); StringBuilder memory ringSvg = SB.create(4096); for(uint i=0; i<16; i++) { uint channelIndex = (i >> 1); if(atr.density[channelIndex] == 0) continue; int span = rings[i].span; uint segs = 8 >> uint(Random.range(rand, 1, 2)); int[] memory sections = new int[](segs); for(uint g=0; g<segs; g++) { sections[g] = 1; } { int increments = int(span)-int(segs); for(int s=0; s<increments; s++) { sections[uint(Random.range(rand, 0, int(segs) - 1))]++; } } int progress = int(span); // template SB.writeStr(b, "<g id='variant_r"); SB.writeUint(b, rings[i].id); SB.writeStr(b, "_v0'>"); for(uint t=0; t<segs; t++) { progress -= int(sections[t]); // TODO make sure everything with subtractions happens with ints SegmentData memory segmentData; segmentData.ringId = i; segmentData.segId = t; segmentData.inner = rings[i].inner; segmentData.outer = rings[i].outer; segmentData.thick = rings[i].outer - int(rings[i].inner); segmentData.start = progress * 5; segmentData.fin = sections[t] * 5; segmentData.edge = EdgeType(rings[i].inner % 2); { int maxIntricacy = atr.intricacy[channelIndex] >> 3; segmentData.fill = FillType(Random.range(rand, 2, 2+maxIntricacy)); segmentData.innerSpanType = SpanType(Random.range(rand, 2, 2+maxIntricacy)); segmentData.outerSpanType = SpanType(Random.range(rand, 2, 2+maxIntricacy)); } segmentData.padInner = PadType(rings[i].outer % 2); segmentData.padOuter = PadType(rings[i].outer % 2); segmentData.colour = getSegmentColour(atr, rings[i], rand); if (Random.range(rand, 0, 10) > 7) { segmentData.colour = (segmentData.colour & 0xfefefe) >> 1; } drawSegment( b, segmentData, rand); } SB.writeStr(b, "</g>"); // arc SB.writeStr(ringSvg, "<g id='r"); SB.writeUint(ringSvg, i); SB.writeStr(ringSvg, "'>"); for (uint j = 0; j < uint(rings[i].arcs); j++) { if (Random.range(rand, 0, 64) < atr.decay) { continue; //THIS HAS THE EFFECT I WAS LOOKING FOR. } int chaosAddition = Random.range(rand, 0, 720); int angle = atr.chaos < Random.range(rand, 0, 64) ? rings[i].span : chaosAddition; int rotation = (angle * int(j)) * 5; SB.writeStr(ringSvg, "<g id='r"); SB.writeUint(ringSvg, i); SB.writeStr(ringSvg, "a"); SB.writeUint(ringSvg, j); SB.writeStr(ringSvg, "' transform='rotate("); SB.writeInt(ringSvg, rotation); SB.writeStr(ringSvg, " 320 320)'><use xlink:href='#variant_r"); SB.writeUint(ringSvg, i); SB.writeStr(ringSvg, "_v0'/> </g>"); } uint shifted = 8 << uint(Random.range(rand, 0, 4)); SB.writeStr(ringSvg, "<animateTransform attributeName='transform' attributeType='XML' type='rotate' from='0 320 320' to='"); if (Random.range(rand, 0, 10) > 8) { SB.writeStr(ringSvg, "-"); } SB.writeStr(ringSvg, "360 320 320' dur='"); SB.writeUint(ringSvg, shifted); SB.writeStr(ringSvg, "s' begin='1s' repeatCount='indefinite'/></g>"); } SB.writeStr(b, "</defs>"); SB.concat(b, ringSvg); } function createRings(Rand memory rand) private pure returns(Ring[16] memory) { uint8[8] memory chf = [0, 0, 0, 0, 0, 0, 0, 0]; for(uint i=0; i<24; i++) { chf[uint(Random.range(rand, 0, 7))]++; } int[16] memory radii = [int(5), 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]; for(uint j=0; j<chf.length; j++) { int total = int8(chf[j]); for(int i=0; i<total; i++) { uint lower = j*2; uint upper = (j*2)+3; uint index = uint(Random.range(rand, int(lower), int(upper))); int adv = Random.range(rand, i, total); radii[index % 16]+=(adv*5); total-=adv; } } Ring[16] memory rings; uint8[5] memory increments = [12, 18, 24, 36, 72]; int progress = 60; for(uint i=0; i<16; i++) { uint idxInc = uint(Random.range(rand, 0, int(increments.length)-1)); int increment = int8(increments[idxInc]); int pad = 1; int thisRingThickness = radii[i]; int innerRadius = progress+pad; int outerRadius = int(innerRadius+thisRingThickness) - int(pad); progress += thisRingThickness; int numArcs = 72/increment; rings[i] = Ring( { id : i, arcs : numArcs, span : increment, inner : innerRadius, outer : outerRadius }); } return rings; } function drawSpan( StringBuilder memory b, SpanType spanType, int start, int fin, int radius, PadType pad, Variant variant, uint col, Rand memory rand) private view { if (spanType == SpanType.Arc) { arc(b, start, fin, radius, pad, col, rand); } else if (spanType == SpanType.Dotted) { dotted(b, start, fin, radius, pad, col, rand); } else if (spanType == SpanType.Cap) { cap(b, start, fin, radius, pad, col, rand); } else if (spanType == SpanType.Ang) { ang(b, start, fin, radius, pad, variant, col, rand); } else if (spanType == SpanType.Brk) { brk(b, start, fin, radius, pad, variant, col, rand); } } function drawSegment( StringBuilder memory b, SegmentData memory segmentData, Rand memory rand) private view { SB.writeStr(b, "<g id='r"); SB.writeUint(b, segmentData.ringId); SB.writeStr(b, "v0s"); SB.writeUint(b, segmentData.segId); SB.writeStr(b, "'>"); //draw the inner span drawSpan( b, segmentData.innerSpanType, segmentData.start, segmentData.fin, segmentData.inner, segmentData.padInner, Variant.Inner, segmentData.colour, rand); //draw the outer span drawSpan( b, segmentData.outerSpanType, segmentData.start, segmentData.fin, segmentData.outer, segmentData.padOuter, Variant.Outer, segmentData.colour, rand); //draw the edges (matching) if (segmentData.edge == EdgeType.Simple) { simple( b, segmentData.start, segmentData.fin, segmentData.outer, segmentData.padOuter, segmentData.thick, segmentData.colour, rand); } int radius = segmentData.inner + ((segmentData.outer-segmentData.inner) / 2); if (segmentData.fill == FillType.Block) { blck( b, segmentData.start, segmentData.fin, radius, segmentData.padOuter, segmentData.thick, segmentData.colour, rand); } else if (segmentData.fill == FillType.Increment) { inc( b, segmentData.start, segmentData.fin, radius, segmentData.padOuter, segmentData.thick, segmentData.colour, rand); } else if (segmentData.fill == FillType.Text) { if (!(segmentData.thick < 5 || segmentData.fin < 30)) { text( b, segmentData.start, segmentData.fin, segmentData.inner, segmentData.colour, rand); } } else if (segmentData.fill == FillType.Hollow) { hollow( b, segmentData.start, segmentData.fin, segmentData.inner, segmentData.padOuter, segmentData.thick, segmentData.colour, rand); } else if (segmentData.fill == FillType.Comp) { blck( b, segmentData.start, segmentData.fin, radius, segmentData.padOuter, segmentData.thick, segmentData.colour, rand); inc( b, segmentData.start, segmentData.fin, radius, segmentData.padOuter, segmentData.thick, segmentData.colour, rand); hollow( b, segmentData.start, segmentData.fin, segmentData.inner, segmentData.padOuter, segmentData.thick, segmentData.colour, rand); if (!(segmentData.thick < 5 || segmentData.fin < 30)) { text( b, segmentData.start, segmentData.fin, segmentData.inner, segmentData.colour, rand); } } SB.writeStr(b, "</g>"); } /*fill types*/ function hollow( StringBuilder memory b, int start, int fin, int radius, PadType pad, int thickness, uint col, Rand memory rand) view private { int padding = pad == PadType.Single ? int(2) : int(0); int angleStart = start+padding; int angleEnd = fin-(padding*2); int innerRad = radius + padding; int outerRad = radius + (thickness-padding); int centreRad = 320 + innerRad; int len = centreRad + thickness - (padding*2); SB.writeStr(b, "<g transform='rotate("); SB.writeInt(b, angleStart); SB.writeStr(b, " 320 320)'><line y1='320' x1='"); SB.writeInt(b, centreRad); SB.writeStr(b, "' y2='320' x2='"); SB.writeInt(b, len); SB.writeStr(b, "' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-width='"); SB.writeStr(b, randomStrokeWidth(rand)); SB.writeStr(b, "'/><circle r='"); SB.writeInt(b, innerRad); SB.writeStr(b, "' cx='320' cy='320' fill='none' pathLength='360' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-width='"); SB.writeStr(b, randomStrokeWidth(rand)); SB.writeStr(b, "' stroke-dasharray='"); SB.writeInt(b, angleEnd); SB.writeStr(b, " 360'/><circle r='"); SB.writeInt(b, outerRad); SB.writeStr(b, "' cx='320' cy='320' fill='none' pathLength='360' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-width='"); SB.writeStr(b, randomStrokeWidth(rand)); SB.writeStr(b, "' stroke-dasharray='"); SB.writeInt(b, angleEnd); SB.writeStr(b, " 360'/><g transform='rotate("); SB.writeInt(b, angleEnd); SB.writeStr(b, " 320 320)'><line y1='320' x1='"); SB.writeInt(b, centreRad); SB.writeStr(b, "' y2='320' x2='"); SB.writeInt(b, len); SB.writeStr(b, "' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-width='"); SB.writeStr(b, randomStrokeWidth(rand)); SB.writeStr(b, "'/></g></g>"); } function randomStrokeWidth(Rand memory rand) private pure returns(string memory) { return Random.range(rand, 0, 9) > 6 ? "0.6" : "0.3"; } function text( StringBuilder memory b, int start, int fin, int radius, uint col, Rand memory rand) view private { int padding = 2; int angleStart = start - padding; uint textId = Random.value(rand); string[12] memory sym = ["0.421", "0.36", "0.73","0.421", "0.36", "0.73","0.421", "0.36", "0.73", "+", "^", "_"]; string memory chars = sym[uint(Random.range(rand, 0, int(sym.length)-1))]; radius += FONT_SIZE + padding; SB.writeStr(b, "<g transform='rotate("); SB.writeInt(b, angleStart-180+fin); SB.writeStr(b, " 320 320)'><path id='text_path_"); SB.writeUint(b, textId); SB.writeStr(b, "' d='M"); SB.writeInt(b, 320-radius); SB.writeStr(b, ", 320 a1, 1 0 0, 0 "); SB.writeInt(b, radius*2); SB.writeStr(b, ", 0' pathLength='100' fill='none' stroke-width='0' stroke='red'/><text x='0%' style='fill:#"); SB.writeRgb(b, col); SB.writeStr(b, ";'><textPath href='#text_path_"); SB.writeUint(b, textId); SB.writeStr(b, "' pointer-events='none'>"); SB.writeStr(b, chars); SB.writeStr(b, "</textPath></text></g>"); } function inc( StringBuilder memory b, int start, int fin, int radius, PadType pad, int thickness, uint col, Rand memory rand) view private { int padding = (pad == PadType.Single) ? int(4) : int(0); int angleStart = start + padding / 2; int angleEnd = fin - (padding); int stroke = thickness - padding; uint incId = Random.value(rand); SB.writeStr(b, "<g transform='rotate("); SB.writeInt(b, angleStart); SB.writeStr(b, " 320 320)'><clipPath id='inc_cutter_"); SB.writeUint(b, incId); SB.writeStr(b, "'><rect x='0' y='0' width='640' height='320' stroke='black' fill='none' transform='rotate("); SB.writeInt(b, angleEnd); SB.writeStr(b, ", 320, 320)' /></clipPath><path d='M"); SB.writeInt(b, 320-radius); SB.writeStr(b, ", 320 a1, 1 0 0, 0 "); SB.writeInt(b, radius*2); SB.writeStr(b, ", 0' pathLength='100' fill='none' stroke-width='"); SB.writeInt(b, stroke); SB.writeStr(b, "' stroke-opacity='0.4' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-dasharray='0.05 1' clip-path='url(#inc_cutter_"); SB.writeUint(b, incId); SB.writeStr(b, ")'/></g>"); } function blck( StringBuilder memory b, int start, int /*fin*/, int radius, PadType pad, int thickness, uint col, Rand memory rand) view private { int padding = (pad == PadType.Single) ? int(4) : int(0); int angleStart = start + padding / 2; int stroke = thickness - padding; int opac = Random.range(rand, 2, 8); SB.writeStr(b, "<g transform='rotate("); SB.writeInt(b, angleStart); SB.writeStr(b, " 320 320)'><circle r='"); SB.writeInt(b, radius); SB.writeStr(b, "' cx='320' cy='320' fill='none' pathLength='359' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-opacity='"); SB.writeInt(b, opac); SB.writeStr(b, "%' stroke-width='"); SB.writeInt(b, stroke); SB.writeStr(b, "' stroke-dasharray='"); SB.writeInt(b, angleStart); SB.writeStr(b, " "); SB.writeInt(b, 360 - angleStart); SB.writeStr(b, "'/></g>"); } /*edge types*/ function simple( StringBuilder memory b, int start, int fin, int radius, PadType pad, int len, uint col, Rand memory rand) view private { int padding = (pad == PadType.Single) ? int(1) : int(0); int angleStart = start + padding; int angleEnd = fin - (padding * 2); int centreRad = 320 + radius; int edgeLength = centreRad - len; SB.writeStr(b, "<g transform='rotate("); SB.writeInt(b, angleStart); SB.writeStr(b, " 320 320)'><line y1='320' x1='"); SB.writeInt(b, centreRad); SB.writeStr(b, "' y2='320' x2='"); SB.writeInt(b, edgeLength); SB.writeStr(b, "' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-width='"); SB.writeStr(b, randomStrokeWidth(rand)); SB.writeStr(b, "'/><g transform='rotate("); SB.writeInt(b, angleEnd); SB.writeStr(b, " 320 320)'><line y1='320' x1='"); SB.writeInt(b, centreRad); SB.writeStr(b, "' y2='320' x2='"); SB.writeInt(b, edgeLength); SB.writeStr(b, "' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-width='"); SB.writeStr(b, randomStrokeWidth(rand)); SB.writeStr(b, "'/></g></g>"); } /*spans*/ function brk( StringBuilder memory b, int start, int fin, int radius, PadType pad, Variant variant, uint col, Rand memory rand) view private { int padding = (pad == PadType.Single) ? int(1) : int(0); int angleStart = start + padding; int angleEnd = fin - (padding * 2); int centreRad = 320 + radius; int brkSize = 2; int brkOffset = (variant == Variant.Inner) ? centreRad + brkSize : centreRad - brkSize; //uint brkId = Rand.next(rand); SB.writeStr(b, "<g><circle r='"); SB.writeInt(b, radius); SB.writeStr(b, "' cx='320' cy='320' fill='none' pathLength='359' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-width='"); SB.writeStr(b, randomStrokeWidth(rand)); SB.writeStr(b, "' stroke-dasharray='"); SB.writeInt(b, angleStart); SB.writeStr(b, " "); SB.writeInt(b, 360 - angleStart); SB.writeStr(b, "'/><line y1='320' x1='"); SB.writeInt(b, centreRad); SB.writeStr(b, "' y2='320' x2='"); SB.writeInt(b, brkOffset); SB.writeStr(b, "' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-width='"); SB.writeStr(b, randomStrokeWidth(rand)); SB.writeStr(b, "'/><g transform='rotate("); SB.writeInt(b, angleEnd); SB.writeStr(b, " 320 320)'><line y1='320' x1='"); SB.writeInt(b, centreRad); SB.writeStr(b, "' y2='320' x2='"); SB.writeInt(b, brkOffset); SB.writeStr(b, "' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-width='"); SB.writeStr(b, randomStrokeWidth(rand)); SB.writeStr(b, "'/></g></g>"); } function ang( StringBuilder memory b, int start, int fin, int radius, PadType pad, Variant variant, uint col, Rand memory rand) view private { int padding = (pad == PadType.Single) ? int(1) : int(0); int angleStart = start + padding; int angleEnd = fin - (padding * 2); int angsSize = 2; int centreRad = 320 + radius; int centreAng = (variant == Variant.Inner) ? centreRad + angsSize : centreRad - angsSize; int opac = Random.range(rand, 10, 100); SB.writeStr(b, "<g transform='rotate("); SB.writeInt(b, angleStart); SB.writeStr(b, " 320 320)'><circle r='"); SB.writeInt(b, radius); SB.writeStr(b, "' cx='320' cy='320' fill='none' pathLength='360' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-opacity='"); SB.writeInt(b, opac); SB.writeStr(b, "%' stroke-width='"); SB.writeStr(b, randomStrokeWidth(rand)); SB.writeStr(b, "' stroke-dasharray= '"); SB.writeInt(b, angleEnd); SB.writeStr(b, " 360'/><polyline points='"); SB.writeInt(b, centreAng); SB.writeStr(b, ", 320 "); SB.writeInt(b, centreRad); SB.writeStr(b, ", 320 "); SB.writeInt(b, centreRad); SB.writeStr(b, ", "); SB.writeInt(b, 320+angsSize); SB.writeStr(b, "' stroke-width='"); SB.writeStr(b, randomStrokeWidth(rand)); SB.writeStr(b, "' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' fill='none'/><g transform='rotate("); SB.writeInt(b, angleEnd); SB.writeStr(b, " 320 320)'><polyline points='"); SB.writeInt(b, centreAng); SB.writeStr(b, ", 320 "); SB.writeInt(b, centreRad); SB.writeStr(b, ", 320 "); SB.writeInt(b, centreRad); SB.writeStr(b, ", "); SB.writeInt(b, 320-angsSize); SB.writeStr(b, "' stroke-width='"); SB.writeStr(b, randomStrokeWidth(rand)); SB.writeStr(b, "' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' fill='none'/></g></g>"); } function cap( StringBuilder memory b, int start, int fin, int radius, PadType pad, uint col, Rand memory rand) view private { int padding = (pad == PadType.Single) ? int(1) : int(0); int angleStart = start + padding; int angleEnd = fin - (padding * 2); int gap = angleEnd - 2; SB.writeStr(b, "<g transform='rotate("); SB.writeInt(b, angleStart); SB.writeStr(b, " 320 320)'><circle r='"); SB.writeInt(b, radius); SB.writeStr(b, "' cx='320' cy='320' fill='none' pathLength='360' stroke-opacity='20%' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-width='"); SB.writeStr(b, randomStrokeWidth(rand)); SB.writeStr(b, "' stroke-dasharray='"); SB.writeInt(b, angleEnd); SB.writeStr(b, " 360'/><circle r='"); SB.writeInt(b, radius); SB.writeStr(b, "' cx='320' cy='320' fill='none' pathLength='360' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-width='"); SB.writeStr(b, randomStrokeWidth(rand)); SB.writeStr(b, "' stroke-dasharray='1 "); SB.writeInt(b, gap); SB.writeStr(b, " 1 360'/></g>"); } function dotted( StringBuilder memory b, int start, int fin, int radius, PadType pad, uint col, Rand memory rand) view private { int padding = (pad == PadType.Single) ? int(1) : int(0); int angleStart = start + padding; int angleEnd = fin - (padding * 2); int gap = angleEnd - 2; int opac = Random.range(rand, 10, 100); uint dotId = Random.value(rand); SB.writeStr(b, "<g transform='rotate("); SB.writeInt(b, angleStart); SB.writeStr(b, " 320 320)'><clipPath id='dot_cutter_"); SB.writeUint(b, dotId); SB.writeStr(b, "'><rect x='0' y='0' width='640' height='320' stroke='black' fill='none' transform='rotate("); SB.writeInt(b, angleEnd); SB.writeStr(b, ", 320, 320)' /></clipPath><path d='M"); SB.writeInt(b, 320-radius); SB.writeStr(b, ", 320 a1, 1 0 0, 0 "); SB.writeInt(b, radius*2); SB.writeStr(b, ", 0' pathLength='100' fill='none' stroke-opacity='"); SB.writeInt(b, opac); SB.writeStr(b, "%' stroke-width='0.4' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-dasharray='0.25 0.25' clip-path='url(#dot_cutter_"); SB.writeUint(b, dotId); SB.writeStr(b, ")'/><circle r='"); SB.writeInt(b, radius); SB.writeStr(b, "' cx='320' cy='320' fill='none' pathLength='359' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-width='0.4' stroke-dasharray='1 "); SB.writeInt(b, gap); SB.writeStr(b, " 1 360'/></g>"); } function arc( StringBuilder memory b, int start, int /*fin*/, int radius, PadType pad, uint col, Rand memory rand) view private { int padding = (pad == PadType.Single) ? int(1) : int(0); int angleStart = start + padding; SB.writeStr(b, "<g><circle r='"); SB.writeInt(b, radius); SB.writeStr(b, "' cx='320' cy='320' fill='none' pathLength='359' stroke='#"); SB.writeRgb(b, col); SB.writeStr(b, "' stroke-width='"); SB.writeStr(b, randomStrokeWidth(rand)); SB.writeStr(b, "' stroke-dasharray='"); SB.writeInt(b, angleStart); SB.writeStr(b, " "); SB.writeInt(b, 360 - angleStart); SB.writeStr(b, "'/></g>"); } } contract CypherMetadata is Ownable { using Strings for uint256; CypherDrawing _drawing; string private _imageBaseUri; constructor( CypherDrawing drawing, string memory imageBaseUri) { _drawing = drawing; _imageBaseUri = imageBaseUri; } function tokenURI( uint256 tokenId, bytes32 hash, uint256 generation, bool isFirstTokenInGeneration) public view returns(string memory) { return string(abi.encodePacked("data:application/json;utf8,{" "\"image\":\"data:image/svg+xml;utf8,", _drawing.generate(hash), "\",", _commonMetadata(tokenId, hash, generation, isFirstTokenInGeneration), "}")); } function metadata( uint256 tokenId, bytes32 hash, uint256 generation, bool isFirstTokenInGeneration) public view returns(string memory) { string memory imageUri = bytes(_imageBaseUri).length > 0 ? string(abi.encodePacked(_imageBaseUri, tokenId.toString())) : ""; return string(abi.encodePacked("{" "\"external_url\": \"", imageUri, "\",", "\"image\": \"", imageUri, "\",", _commonMetadata(tokenId, hash, generation, isFirstTokenInGeneration), "}")); } function setDrawing(CypherDrawing drawing) public onlyOwner { _drawing = drawing; } function setImageBaseUri(string memory imageBaseUri) public onlyOwner { _imageBaseUri = imageBaseUri; } function _commonMetadata( uint256 tokenId, bytes32 hash, uint256 generation, bool isFirstTokenInGeneration) private view returns(string memory) { CypherAttributes memory attributes = _drawing.getAttributes(hash); int overall = 0; for (uint i = 0; i < 8; ++i) { overall += attributes.density[i] * attributes.intricacy[i]; } overall >>= 3; StringBuilder memory b = SB.create(2048); SB.writeStr(b, "\"description\": \"Cypher is a generative art project by Hideki Tsukamoto comprised of 1024 tokens calculated and drawn via smart-contract, by the Ethereum Virtual Machine. Cypher is part one of the 'Apex' series.\"," "\"name\": \"Cypher #"); SB.writeUint(b, tokenId); SB.writeStr(b, "\"," "\"background_color\": \"1a181b\"," "\"attributes\": ["); if (tokenId == 0) { SB.writeStr(b, "{" "\"trait_type\": \"Edition\"," "\"value\": \"Genesis\"" "},"); } else if (tokenId == 1) { SB.writeStr(b, "{" "\"trait_type\": \"Edition\"," "\"value\": \"Primary\"" "},"); } else if (tokenId == 2) { SB.writeStr(b, "{" "\"trait_type\": \"Edition\"," "\"value\": \"Secondary\"" "},"); } else if (tokenId == 3) { SB.writeStr(b, "{" "\"trait_type\": \"Edition\"," "\"value\": \"Tertiary\"" "},"); } if (isFirstTokenInGeneration) { SB.writeStr(b, "{" "\"trait_type\": \"Edition\"," "\"value\": \"Generation Genesis\"" "},"); } SB.writeStr(b, "{" "\"trait_type\": \"Generation\"," "\"value\": \""); SB.writeUint(b, generation); SB.writeStr(b, "\"}," "{" "\"trait_type\": \"Intricacy\"," "\"value\":\""); SB.writeStr(b, _attributeValueString_0_32(overall)); SB.writeStr(b, "\"}," "{" "\"trait_type\": \"Intricacy Value\"," "\"max_value\": 32," "\"value\":"); SB.writeInt(b, overall); SB.writeStr(b, "}," "{" "\"trait_type\": \"Chaos\"," "\"value\":\""); SB.writeStr(b, _attributeValueString_0_32(attributes.chaos)); SB.writeStr(b, "\"}," "{" "\"trait_type\": \"Chaos Value\"," "\"max_value\": 32," "\"value\":"); SB.writeInt(b, attributes.chaos); SB.writeStr(b, "}," "{" "\"trait_type\": \"Channels\"," "\"value\":\""); SB.writeStr(b, _attributeValueString_0_8(attributes.numChannels)); SB.writeStr(b, "\"}," "{" "\"trait_type\": \"Channels Value\"," "\"max_value\": 8," "\"value\":"); SB.writeInt(b, attributes.numChannels); SB.writeStr(b, "}," "{" "\"trait_type\": \"Decay\"," "\"value\":\""); SB.writeStr(b, _attributeValueString_0_32(attributes.decay)); SB.writeStr(b, "\"}," "{" "\"trait_type\": \"Decay Value\"," "\"max_value\": 32," "\"value\":"); SB.writeInt(b, attributes.decay); SB.writeStr(b, "}," "{" "\"trait_type\": \"Level\"," "\"value\":\""); SB.writeUint(b, attributes.colorset + 1); SB.writeStr(b, "\"}," "{" "\"trait_type\": \"Level Value\"," "\"max_value\": 5," "\"value\":"); SB.writeUint(b, attributes.colorset + 1); SB.writeStr(b, "}" "]"); return SB.getString(b); } function _attributeValueString_0_32(int256 value) private pure returns(string memory) { if (value == 0) { return "Void"; } else if (value <= 2) { return "Marginal"; } else if (value <= 8) { return "Low"; } else if (value <= 23) { return "Average"; } else if (value <= 29) { return "High"; } else if (value <= 31) { return "Super"; } else { return "Extreme"; } } function _attributeValueString_0_8(int256 value) private pure returns(string memory) { if (value == 0) { return "Void"; } else if (value <= 1) { return "Marginal"; } else if (value <= 2) { return "Low"; } else if (value <= 5) { return "Average"; } else if (value <= 6) { return "High"; } else if (value <= 7) { return "Super"; } else { return "Extreme"; } } } contract Cypher is ERC721Enumerable, Ownable { uint256 private _maxTokenInvocations; uint256 private _reservedInvocations; uint256 private _auctionStartBlock; uint256 private _auctionEndBlock; uint256 private _initialFee; uint256 private _initialDuration; uint256 private _maxHalvings; address payable private _recipient; CypherDrawing private _drawing; CypherMetadata private _metadata; mapping(uint256 => bytes32) private _hashes; mapping(uint256 => uint256) private _generation; bool _isLocked; struct ConstructorArgs { string name; string symbol; uint256 maxTokenInvocations; uint256 reservedInvocations; uint256 auctionStartBlock; uint256 initialFee; uint256 initialDuration; uint256 maxHalvings; address payable recipient; CypherDrawing drawing; CypherMetadata meta; } constructor( ConstructorArgs memory args) ERC721(args.name, args.symbol) { _maxTokenInvocations = args.maxTokenInvocations; _reservedInvocations = args.reservedInvocations; _auctionStartBlock = args.auctionStartBlock; _initialFee = args.initialFee; _initialDuration = args.initialDuration; _maxHalvings = args.maxHalvings; _recipient = args.recipient; _drawing = args.drawing; _metadata = args.meta; // minting #0 bytes32 hash = keccak256( abi.encodePacked(uint(0), blockhash(block.number - 1))); _hashes[0] = hash; _generation[0] = 0; _safeMint(msg.sender, 0); } modifier isUnlocked() { require(!_isLocked, "Contract is locked"); _; } function lock() public onlyOwner { _isLocked = true; } function setMaxTokenInvocations(uint256 maxTokenInvocations) public onlyOwner isUnlocked { _maxTokenInvocations = maxTokenInvocations; } function setReservedInvocations(uint256 reservedInvocations) public onlyOwner isUnlocked { _reservedInvocations = reservedInvocations; } function setAuctionStartBlock(uint256 auctionStartBlock) public onlyOwner isUnlocked { _auctionStartBlock = auctionStartBlock; } function setInitialFee(uint256 initialFee) public onlyOwner isUnlocked { _initialFee = initialFee; } function setInitialDuration(uint256 initialDuration) public onlyOwner isUnlocked { _initialDuration = initialDuration; } function setMaxHalvings(uint256 maxHalvings) public onlyOwner isUnlocked { _maxHalvings = maxHalvings; } function setRecipient(address payable recipient) public onlyOwner { _recipient = recipient; } function setDrawingContract(CypherDrawing drawing) public onlyOwner isUnlocked { _drawing = drawing; } function setMetadataContract(CypherMetadata meta) public onlyOwner { _metadata = meta; } function getInfo() public view returns( bool hasStarted, bool hasEnded, uint256 blocksUntilAuctionStart, uint256 currentGeneration, uint256 currentFee, uint256 blocksUntilNextHalving, uint256 currentInvocationCount, uint256 maxTokenInvocations) { uint256 nextBlock = block.number + 1; if (nextBlock >= _auctionStartBlock) { hasStarted = _auctionStartBlock != 0; blocksUntilAuctionStart = 0; } else { hasStarted = false; blocksUntilAuctionStart = _auctionStartBlock - nextBlock; } if (_auctionEndBlock == 0) { hasEnded = false; (currentGeneration, currentFee, blocksUntilNextHalving) = _getAuctionState(nextBlock); } else { hasEnded = true; (currentGeneration, currentFee, ) = _getAuctionState(_auctionEndBlock); blocksUntilNextHalving = 0; } currentInvocationCount = totalSupply(); maxTokenInvocations = _maxTokenInvocations; } function purchase() public payable returns (uint256 tokenId) { require(_auctionStartBlock > 0 && block.number >= _auctionStartBlock, "auction hasn't started yet"); uint256 totalInvocations = totalSupply(); uint256 invocationsRemaining = _maxTokenInvocations - totalInvocations; require(invocationsRemaining > _reservedInvocations || (invocationsRemaining > 0 && msg.sender == owner()), "max token invocations reached"); uint256 blockNumber = block.number; if (_auctionEndBlock != 0) { blockNumber = _auctionEndBlock; } else if (invocationsRemaining == (_reservedInvocations + 1)) { _auctionEndBlock = block.number; } uint256 generation; uint256 fee; (generation, fee, ) = _getAuctionState(blockNumber); require(msg.value == fee, "value doesn't equal cost"); (bool success, ) = _recipient.call{value:msg.value}(""); require(success, "Transfer failed."); tokenId = totalInvocations; bytes32 hash = keccak256( abi.encodePacked(tokenId, blockhash(block.number - 1), tokenId > 0 ? _hashes[tokenId - 1] : bytes32(0))); _hashes[tokenId] = hash; _generation[tokenId] = generation; _safeMint(msg.sender, tokenId); return tokenId; } function metadata(uint256 tokenId) public view returns (string memory) { require(_exists(tokenId), "token not minted"); return _metadata.metadata( tokenId, _hashes[tokenId], _generation[tokenId], _isFirstTokenInGeneration(tokenId)); } function generate(uint256 tokenId) public view returns (string memory) { require(_exists(tokenId), "token not minted"); return _drawing.generate(_hashes[tokenId]); } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "token not minted"); return _metadata.tokenURI( tokenId, _hashes[tokenId], _generation[tokenId], _isFirstTokenInGeneration(tokenId)); } function _getAuctionState(uint256 blockNumber) private view returns ( uint256 currentGeneration, uint256 currentFee, uint256 blocksUntilNextHalving) { if (_auctionStartBlock == 0) { return (0, _initialFee, 0); } if (blockNumber < _auctionStartBlock) { uint256 firstHalving = _auctionStartBlock + _initialDuration; return (0, _initialFee, firstHalving - blockNumber); } uint256 generation = 0; uint256 fee = _initialFee; uint256 duration = _initialDuration; uint256 nextHalving = _auctionStartBlock + duration; for (uint256 i = 0; i < _maxHalvings; ++i) { if (blockNumber < nextHalving) { return (generation, fee, nextHalving - blockNumber); } ++generation; fee >>= 1; duration <<= 1; nextHalving += duration; } return (generation, fee, 0); } function _isFirstTokenInGeneration(uint256 tokenId) private view returns(bool) { if (tokenId > 0) { return _generation[tokenId] != _generation[tokenId - 1]; } return true; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"maxTokenInvocations","type":"uint256"},{"internalType":"uint256","name":"reservedInvocations","type":"uint256"},{"internalType":"uint256","name":"auctionStartBlock","type":"uint256"},{"internalType":"uint256","name":"initialFee","type":"uint256"},{"internalType":"uint256","name":"initialDuration","type":"uint256"},{"internalType":"uint256","name":"maxHalvings","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"contract CypherDrawing","name":"drawing","type":"address"},{"internalType":"contract CypherMetadata","name":"meta","type":"address"}],"internalType":"struct Cypher.ConstructorArgs","name":"args","type":"tuple"}],"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"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"generate","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":[],"name":"getInfo","outputs":[{"internalType":"bool","name":"hasStarted","type":"bool"},{"internalType":"bool","name":"hasEnded","type":"bool"},{"internalType":"uint256","name":"blocksUntilAuctionStart","type":"uint256"},{"internalType":"uint256","name":"currentGeneration","type":"uint256"},{"internalType":"uint256","name":"currentFee","type":"uint256"},{"internalType":"uint256","name":"blocksUntilNextHalving","type":"uint256"},{"internalType":"uint256","name":"currentInvocationCount","type":"uint256"},{"internalType":"uint256","name":"maxTokenInvocations","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":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"metadata","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"purchase","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"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":"uint256","name":"auctionStartBlock","type":"uint256"}],"name":"setAuctionStartBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract CypherDrawing","name":"drawing","type":"address"}],"name":"setDrawingContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"initialDuration","type":"uint256"}],"name":"setInitialDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"initialFee","type":"uint256"}],"name":"setInitialFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxHalvings","type":"uint256"}],"name":"setMaxHalvings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxTokenInvocations","type":"uint256"}],"name":"setMaxTokenInvocations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract CypherMetadata","name":"meta","type":"address"}],"name":"setMetadataContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"recipient","type":"address"}],"name":"setRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"reservedInvocations","type":"uint256"}],"name":"setReservedInvocations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162003190380380620031908339810160408190526200003491620009a3565b80516020808301518251909162000051916000918501906200081c565b508051620000679060019060208401906200081c565b505050620000846200007e620001af60201b60201c565b620001b3565b6040810151600b556060810151600c556080810151600d5560a0810151600f5560c081015160105560e0810151601155610100810151601280546001600160a01b039283166001600160a01b03199182161790915561012083015160138054918416918316919091179055610140830151601480549190931691161790556000806200011260014362000bae565b406040516020016200012e929190918252602082015260400190565b60408051601f19818403018152919052805160209182012060008080527fa31547ce6245cdb9ecea19cf8c7eb9f5974025bb4075011409251ae855b30aed82905560169092527f0263c2b778d062355049effc2dece97bc6547ff8a88a3258daa512061c2153dd8290559150620001a790339062000205565b505062000c90565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b620002278282604051806020016040528060008152506200022b60201b60201c565b5050565b62000237838362000273565b620002466000848484620003c9565b6200026e5760405162461bcd60e51b8152600401620002659062000b15565b60405180910390fd5b505050565b6001600160a01b038216620002cb5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640162000265565b6000818152600260205260409020546001600160a01b031615620003325760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640162000265565b6200034060008383620004f9565b6001600160a01b03821660009081526003602052604081208054600192906200036b90849062000b93565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000620003ea846001600160a01b0316620005d560201b6200151c1760201c565b15620004ed57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906200042490339089908890889060040162000abf565b602060405180830381600087803b1580156200043f57600080fd5b505af192505050801562000472575060408051601f3d908101601f191682019092526200046f9181019062000970565b60015b620004d2573d808015620004a3576040519150601f19603f3d011682016040523d82523d6000602084013e620004a8565b606091505b508051620004ca5760405162461bcd60e51b8152600401620002659062000b15565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050620004f1565b5060015b949350505050565b620005118383836200026e60201b620008c91760201c565b6001600160a01b0383166200056f576200056981600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b62000595565b816001600160a01b0316836001600160a01b0316146200059557620005958382620005db565b6001600160a01b038216620005af576200026e8162000688565b826001600160a01b0316826001600160a01b0316146200026e576200026e828262000742565b3b151590565b60006001620005f5846200079360201b62000f711760201c565b62000601919062000bae565b60008381526007602052604090205490915080821462000655576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906200069c9060019062000bae565b60008381526009602052604081205460088054939450909284908110620006c757620006c762000c64565b906000526020600020015490508060088381548110620006eb57620006eb62000c64565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548062000726576200072662000c4e565b6001900381819060005260206000200160009055905550505050565b60006200075a836200079360201b62000f711760201c565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b60006001600160a01b038216620008005760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840162000265565b506001600160a01b031660009081526003602052604090205490565b8280546200082a9062000bfb565b90600052602060002090601f0160209004810192826200084e576000855562000899565b82601f106200086957805160ff191683800117855562000899565b8280016001018555821562000899579182015b82811115620008995782518255916020019190600101906200087c565b50620008a7929150620008ab565b5090565b5b80821115620008a75760008155600101620008ac565b80516001600160a01b0381168114620008da57600080fd5b919050565b600082601f830112620008f157600080fd5b81516001600160401b03808211156200090e576200090e62000c7a565b604051601f8301601f19908116603f0116810190828211818310171562000939576200093962000c7a565b816040528381528660208588010111156200095357600080fd5b6200096684602083016020890162000bc8565b9695505050505050565b6000602082840312156200098357600080fd5b81516001600160e01b0319811681146200099c57600080fd5b9392505050565b600060208284031215620009b657600080fd5b81516001600160401b0380821115620009ce57600080fd5b908301906101608286031215620009e457600080fd5b620009ee62000b67565b825182811115620009fe57600080fd5b62000a0c87828601620008df565b82525060208301518281111562000a2257600080fd5b62000a3087828601620008df565b60208301525060408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e0820152610100915062000a84828401620008c2565b82820152610120915062000a9a828401620008c2565b82820152610140915062000ab0828401620008c2565b91810191909152949350505050565b600060018060a01b03808716835280861660208401525083604083015260806060830152825180608084015262000afe8160a085016020870162000bc8565b601f01601f19169190910160a00195945050505050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60405161016081016001600160401b038111828210171562000b8d5762000b8d62000c7a565b60405290565b6000821982111562000ba95762000ba962000c38565b500190565b60008282101562000bc35762000bc362000c38565b500390565b60005b8381101562000be557818101518382015260200162000bcb565b8381111562000bf5576000848401525b50505050565b600181811c9082168062000c1057607f821691505b6020821081141562000c3257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6124f08062000ca06000396000f3fe60806040526004361061017e5760003560e01c806301ffc9a714610183578063066208de146101b857806306fdde03146101da578063081812fc146101fc578063092e59c614610234578063095ea7b31461025457806318160ddd1461027457806323b872dd146102935780632464bb5a146102b35780632f745c59146102d35780633bbed4a0146102f357806342842e0e146103135780634a7dd523146103335780634f6ccce7146103535780635a9b0b89146103735780636352211e146103c557806364edfbf0146103e557806370a08231146103ed578063715018a61461040d578063814121a5146104225780638da5cb5b1461044257806395d89b4114610457578063a22cb4651461046c578063b88d4fde1461048c578063bdf1e06d146104ac578063c13fabaf146104cc578063c87b56dd146104ec578063e3684e391461050c578063e5187f431461052c578063e985e9c51461054c578063ec7c64491461056c578063f2fde38b1461058c578063f83d08ba146105ac575b600080fd5b34801561018f57600080fd5b506101a361019e36600461209c565b6105c1565b60405190151581526020015b60405180910390f35b3480156101c457600080fd5b506101d86101d336600461214c565b6105ec565b005b3480156101e657600080fd5b506101ef61064c565b6040516101af91906121ce565b34801561020857600080fd5b5061021c61021736600461214c565b6106de565b6040516001600160a01b0390911681526020016101af565b34801561024057600080fd5b506101d861024f36600461214c565b610766565b34801561026057600080fd5b506101d861026f366004612070565b6107bd565b34801561028057600080fd5b506008545b6040519081526020016101af565b34801561029f57600080fd5b506101d86102ae366004611f4e565b6108ce565b3480156102bf57600080fd5b506101d86102ce36600461214c565b6108ff565b3480156102df57600080fd5b506102856102ee366004612070565b610956565b3480156102ff57600080fd5b506101d861030e366004611ef1565b6109ec565b34801561031f57600080fd5b506101d861032e366004611f4e565b610a3d565b34801561033f57600080fd5b506101ef61034e36600461214c565b610a58565b34801561035f57600080fd5b5061028561036e36600461214c565b610b15565b34801561037f57600080fd5b50610388610ba8565b6040805198151589529615156020890152958701949094526060860192909252608085015260a084015260c083015260e0820152610100016101af565b3480156103d157600080fd5b5061021c6103e036600461214c565b610c3c565b610285610cb3565b3480156103f957600080fd5b50610285610408366004611ef1565b610f71565b34801561041957600080fd5b506101d8610ff8565b34801561042e57600080fd5b506101d861043d36600461214c565b611033565b34801561044e57600080fd5b5061021c61108a565b34801561046357600080fd5b506101ef611099565b34801561047857600080fd5b506101d861048736600461203d565b6110a8565b34801561049857600080fd5b506101d86104a7366004611f8f565b611169565b3480156104b857600080fd5b506101d86104c7366004611ef1565b6111a1565b3480156104d857600080fd5b506101d86104e736600461214c565b611215565b3480156104f857600080fd5b506101ef61050736600461214c565b61126c565b34801561051857600080fd5b506101ef61052736600461214c565b611306565b34801561053857600080fd5b506101d8610547366004611ef1565b611368565b34801561055857600080fd5b506101a3610567366004611f15565b6113b9565b34801561057857600080fd5b506101d861058736600461214c565b6113e7565b34801561059857600080fd5b506101d86105a7366004611ef1565b61143e565b3480156105b857600080fd5b506101d86114de565b60006001600160e01b0319821663780e9d6360e01b14806105e657506105e682611522565b92915050565b336105f561108a565b6001600160a01b0316146106245760405162461bcd60e51b815260040161061b90612233565b60405180910390fd5b60175460ff16156106475760405162461bcd60e51b815260040161061b906122e3565b601055565b60606000805461065b906123c1565b80601f0160208091040260200160405190810160405280929190818152602001828054610687906123c1565b80156106d45780601f106106a9576101008083540402835291602001916106d4565b820191906000526020600020905b8154815290600101906020018083116106b757829003601f168201915b5050505050905090565b60006106e982611572565b61074a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161061b565b506000908152600460205260409020546001600160a01b031690565b3361076f61108a565b6001600160a01b0316146107955760405162461bcd60e51b815260040161061b90612233565b60175460ff16156107b85760405162461bcd60e51b815260040161061b906122e3565b600f55565b60006107c882610c3c565b9050806001600160a01b0316836001600160a01b031614156108365760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161061b565b336001600160a01b0382161480610852575061085281336113b9565b6108bf5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b606482015260840161061b565b6108c9838361158f565b505050565b6108d833826115fd565b6108f45760405162461bcd60e51b815260040161061b90612268565b6108c98383836116c7565b3361090861108a565b6001600160a01b03161461092e5760405162461bcd60e51b815260040161061b90612233565b60175460ff16156109515760405162461bcd60e51b815260040161061b906122e3565b600d55565b600061096183610f71565b82106109c35760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161061b565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b336109f561108a565b6001600160a01b031614610a1b5760405162461bcd60e51b815260040161061b90612233565b601280546001600160a01b0319166001600160a01b0392909216919091179055565b6108c983838360405180602001604052806000815250611169565b6060610a6382611572565b610a7f5760405162461bcd60e51b815260040161061b906122b9565b601354600083815260156020526040908190205490516304a9bd7d60e21b81526001600160a01b03909216916312a6f5f491610ac19160040190815260200190565b60006040518083038186803b158015610ad957600080fd5b505afa158015610aed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105e691908101906120d6565b6000610b2060085490565b8210610b835760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161061b565b60088281548110610b9657610b96612443565b90600052602060002001549050919050565b60008080808080808080610bbd436001612366565b9050600d548110610bd857600d541515985060009650610bed565b6000985080600d54610bea919061237e565b96505b600e54610c0d5760009750610c0181611860565b91975095509350610c27565b60019750610c1c600e54611860565b509096509450600093505b6008549250600b549150509091929394959697565b6000818152600260205260408120546001600160a01b0316806105e65760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b606482015260840161061b565b600080600d54118015610cc85750600d544310155b610d115760405162461bcd60e51b815260206004820152601a602482015279185d58dd1a5bdb881a185cdb89dd081cdd185c9d1959081e595d60321b604482015260640161061b565b6000610d1c60085490565b9050600081600b54610d2e919061237e565b9050600c54811180610d635750600081118015610d635750610d4e61108a565b6001600160a01b0316336001600160a01b0316145b610daf5760405162461bcd60e51b815260206004820152601d60248201527f6d617820746f6b656e20696e766f636174696f6e732072656163686564000000604482015260640161061b565b600e54439015610dc25750600e54610ddc565b600c54610dd0906001612366565b821415610ddc5743600e555b600080610de883611860565b509092509050348114610e385760405162461bcd60e51b81526020600482015260186024820152771d985b1d5948191bd95cdb89dd08195c5d585b0818dbdcdd60421b604482015260640161061b565b6012546040516000916001600160a01b03169034908381818185875af1925050503d8060008114610e85576040519150601f19603f3d011682016040523d82523d6000602084013e610e8a565b606091505b5050905080610ece5760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b604482015260640161061b565b859650600087600143610ee1919061237e565b4060008a11610ef1576000610f10565b60156000610f0060018d61237e565b8152602001908152602001600020545b604080516020810194909452830191909152606082015260800160408051601f19818403018152918152815160209283012060008b815260158452828120829055601690935291208590559050610f67338961194f565b5050505050505090565b60006001600160a01b038216610fdc5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161061b565b506001600160a01b031660009081526003602052604090205490565b3361100161108a565b6001600160a01b0316146110275760405162461bcd60e51b815260040161061b90612233565b611031600061196d565b565b3361103c61108a565b6001600160a01b0316146110625760405162461bcd60e51b815260040161061b90612233565b60175460ff16156110855760405162461bcd60e51b815260040161061b906122e3565b600c55565b600a546001600160a01b031690565b60606001805461065b906123c1565b6001600160a01b0382163314156110fd5760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b604482015260640161061b565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61117333836115fd565b61118f5760405162461bcd60e51b815260040161061b90612268565b61119b848484846119bf565b50505050565b336111aa61108a565b6001600160a01b0316146111d05760405162461bcd60e51b815260040161061b90612233565b60175460ff16156111f35760405162461bcd60e51b815260040161061b906122e3565b601380546001600160a01b0319166001600160a01b0392909216919091179055565b3361121e61108a565b6001600160a01b0316146112445760405162461bcd60e51b815260040161061b90612233565b60175460ff16156112675760405162461bcd60e51b815260040161061b906122e3565b601155565b606061127782611572565b6112935760405162461bcd60e51b815260040161061b906122b9565b6014546000838152601560209081526040808320546016909252909120546001600160a01b0390921691637e99d4f29185916112ce836119f2565b6040516001600160e01b031960e087901b16815260048101949094526024840192909252604483015215156064820152608401610ac1565b606061131182611572565b61132d5760405162461bcd60e51b815260040161061b906122b9565b6014546000838152601560209081526040808320546016909252909120546001600160a01b0390921691633e47894a9185916112ce836119f2565b3361137161108a565b6001600160a01b0316146113975760405162461bcd60e51b815260040161061b90612233565b601480546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b336113f061108a565b6001600160a01b0316146114165760405162461bcd60e51b815260040161061b90612233565b60175460ff16156114395760405162461bcd60e51b815260040161061b906122e3565b600b55565b3361144761108a565b6001600160a01b03161461146d5760405162461bcd60e51b815260040161061b90612233565b6001600160a01b0381166114d25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161061b565b6114db8161196d565b50565b336114e761108a565b6001600160a01b03161461150d5760405162461bcd60e51b815260040161061b90612233565b6017805460ff19166001179055565b3b151590565b60006001600160e01b031982166380ac58cd60e01b148061155357506001600160e01b03198216635b5e139f60e01b145b806105e657506301ffc9a760e01b6001600160e01b03198316146105e6565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906115c482610c3c565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061160882611572565b6116695760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161061b565b600061167483610c3c565b9050806001600160a01b0316846001600160a01b031614806116af5750836001600160a01b03166116a4846106de565b6001600160a01b0316145b806116bf57506116bf81856113b9565b949350505050565b826001600160a01b03166116da82610c3c565b6001600160a01b0316146117425760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161061b565b6001600160a01b0382166117a45760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161061b565b6117af838383611a3d565b6117ba60008261158f565b6001600160a01b03831660009081526003602052604081208054600192906117e390849061237e565b90915550506001600160a01b0382166000908152600360205260408120805460019290611811908490612366565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03868116918217909255915184939187169160008051602061249b83398151915291a4505050565b6000806000600d546000141561187f575050600f546000915081611948565b600d548410156118ba576000601054600d5461189b9190612366565b90506000600f5486836118ae919061237e565b93509350935050611948565b600f54601054600d54600092919083906118d5908390612366565b905060005b60115481101561193a57818910156119085784846118f88b8561237e565b9750975097505050505050611948565b611911856123fc565b9450600193841c939290921b916119288383612366565b9150611933816123fc565b90506118da565b509295509093506000925050505b9193909250565b611969828260405180602001604052806000815250611af5565b5050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6119ca8484846116c7565b6119d684848484611b28565b61119b5760405162461bcd60e51b815260040161061b906121e1565b60008115611a355760166000611a0960018561237e565b815260200190815260200160002054601660008481526020019081526020016000205414159050919050565b506001919050565b6001600160a01b038316611a9857611a9381600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b611abb565b816001600160a01b0316836001600160a01b031614611abb57611abb8382611c35565b6001600160a01b038216611ad2576108c981611cd2565b826001600160a01b0316826001600160a01b0316146108c9576108c98282611d81565b611aff8383611dc5565b611b0c6000848484611b28565b6108c95760405162461bcd60e51b815260040161061b906121e1565b60006001600160a01b0384163b15611c2a57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611b6c903390899088908890600401612191565b602060405180830381600087803b158015611b8657600080fd5b505af1925050508015611bb6575060408051601f3d908101601f19168201909252611bb3918101906120b9565b60015b611c10573d808015611be4576040519150601f19603f3d011682016040523d82523d6000602084013e611be9565b606091505b508051611c085760405162461bcd60e51b815260040161061b906121e1565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506116bf565b506001949350505050565b60006001611c4284610f71565b611c4c919061237e565b600083815260076020526040902054909150808214611c9f576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090611ce49060019061237e565b60008381526009602052604081205460088054939450909284908110611d0c57611d0c612443565b906000526020600020015490508060088381548110611d2d57611d2d612443565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480611d6557611d6561242d565b6001900381819060005260206000200160009055905550505050565b6000611d8c83610f71565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b038216611e1b5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161061b565b611e2481611572565b15611e705760405162461bcd60e51b815260206004820152601c60248201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b604482015260640161061b565b611e7c60008383611a3d565b6001600160a01b0382166000908152600360205260408120805460019290611ea5908490612366565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b038616908117909155905183929060008051602061249b833981519152908290a45050565b600060208284031215611f0357600080fd5b8135611f0e8161246f565b9392505050565b60008060408385031215611f2857600080fd5b8235611f338161246f565b91506020830135611f438161246f565b809150509250929050565b600080600060608486031215611f6357600080fd5b8335611f6e8161246f565b92506020840135611f7e8161246f565b929592945050506040919091013590565b60008060008060808587031215611fa557600080fd5b8435611fb08161246f565b93506020850135611fc08161246f565b92506040850135915060608501356001600160401b03811115611fe257600080fd5b8501601f81018713611ff357600080fd5b80356120066120018261233f565b61230f565b81815288602083850101111561201b57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b6000806040838503121561205057600080fd5b823561205b8161246f565b915060208301358015158114611f4357600080fd5b6000806040838503121561208357600080fd5b823561208e8161246f565b946020939093013593505050565b6000602082840312156120ae57600080fd5b8135611f0e81612484565b6000602082840312156120cb57600080fd5b8151611f0e81612484565b6000602082840312156120e857600080fd5b81516001600160401b038111156120fe57600080fd5b8201601f8101841361210f57600080fd5b805161211d6120018261233f565b81815285602083850101111561213257600080fd5b612143826020830160208601612395565b95945050505050565b60006020828403121561215e57600080fd5b5035919050565b6000815180845261217d816020860160208601612395565b601f01601f19169290920160200192915050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906121c490830184612165565b9695505050505050565b602081526000611f0e6020830184612165565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60208082526010908201526f1d1bdad95b881b9bdd081b5a5b9d195960821b604082015260600190565b60208082526012908201527110dbdb9d1c9858dd081a5cc81b1bd8dad95960721b604082015260600190565b604051601f8201601f191681016001600160401b038111828210171561233757612337612459565b604052919050565b60006001600160401b0382111561235857612358612459565b50601f01601f191660200190565b6000821982111561237957612379612417565b500190565b60008282101561239057612390612417565b500390565b60005b838110156123b0578181015183820152602001612398565b8381111561119b5750506000910152565b600181811c908216806123d557607f821691505b602082108114156123f657634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561241057612410612417565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146114db57600080fd5b6001600160e01b0319811681146114db57600080fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122090b21747925068e2b95a809dfd2235f6a2462418c2d9737be1b7237b1f8bdc7764736f6c634300080600330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003782dace9d900000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000040519d946311449b33d6b03bb40892faeef12d75000000000000000000000000bd9aa94b28e6362fc610d485ce779ef6baa041aa000000000000000000000000f8ee8798f1fbd48f95ca70d2a68fdda404660b550000000000000000000000000000000000000000000000000000000000000006437970686572000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044350485200000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x60806040526004361061017e5760003560e01c806301ffc9a714610183578063066208de146101b857806306fdde03146101da578063081812fc146101fc578063092e59c614610234578063095ea7b31461025457806318160ddd1461027457806323b872dd146102935780632464bb5a146102b35780632f745c59146102d35780633bbed4a0146102f357806342842e0e146103135780634a7dd523146103335780634f6ccce7146103535780635a9b0b89146103735780636352211e146103c557806364edfbf0146103e557806370a08231146103ed578063715018a61461040d578063814121a5146104225780638da5cb5b1461044257806395d89b4114610457578063a22cb4651461046c578063b88d4fde1461048c578063bdf1e06d146104ac578063c13fabaf146104cc578063c87b56dd146104ec578063e3684e391461050c578063e5187f431461052c578063e985e9c51461054c578063ec7c64491461056c578063f2fde38b1461058c578063f83d08ba146105ac575b600080fd5b34801561018f57600080fd5b506101a361019e36600461209c565b6105c1565b60405190151581526020015b60405180910390f35b3480156101c457600080fd5b506101d86101d336600461214c565b6105ec565b005b3480156101e657600080fd5b506101ef61064c565b6040516101af91906121ce565b34801561020857600080fd5b5061021c61021736600461214c565b6106de565b6040516001600160a01b0390911681526020016101af565b34801561024057600080fd5b506101d861024f36600461214c565b610766565b34801561026057600080fd5b506101d861026f366004612070565b6107bd565b34801561028057600080fd5b506008545b6040519081526020016101af565b34801561029f57600080fd5b506101d86102ae366004611f4e565b6108ce565b3480156102bf57600080fd5b506101d86102ce36600461214c565b6108ff565b3480156102df57600080fd5b506102856102ee366004612070565b610956565b3480156102ff57600080fd5b506101d861030e366004611ef1565b6109ec565b34801561031f57600080fd5b506101d861032e366004611f4e565b610a3d565b34801561033f57600080fd5b506101ef61034e36600461214c565b610a58565b34801561035f57600080fd5b5061028561036e36600461214c565b610b15565b34801561037f57600080fd5b50610388610ba8565b6040805198151589529615156020890152958701949094526060860192909252608085015260a084015260c083015260e0820152610100016101af565b3480156103d157600080fd5b5061021c6103e036600461214c565b610c3c565b610285610cb3565b3480156103f957600080fd5b50610285610408366004611ef1565b610f71565b34801561041957600080fd5b506101d8610ff8565b34801561042e57600080fd5b506101d861043d36600461214c565b611033565b34801561044e57600080fd5b5061021c61108a565b34801561046357600080fd5b506101ef611099565b34801561047857600080fd5b506101d861048736600461203d565b6110a8565b34801561049857600080fd5b506101d86104a7366004611f8f565b611169565b3480156104b857600080fd5b506101d86104c7366004611ef1565b6111a1565b3480156104d857600080fd5b506101d86104e736600461214c565b611215565b3480156104f857600080fd5b506101ef61050736600461214c565b61126c565b34801561051857600080fd5b506101ef61052736600461214c565b611306565b34801561053857600080fd5b506101d8610547366004611ef1565b611368565b34801561055857600080fd5b506101a3610567366004611f15565b6113b9565b34801561057857600080fd5b506101d861058736600461214c565b6113e7565b34801561059857600080fd5b506101d86105a7366004611ef1565b61143e565b3480156105b857600080fd5b506101d86114de565b60006001600160e01b0319821663780e9d6360e01b14806105e657506105e682611522565b92915050565b336105f561108a565b6001600160a01b0316146106245760405162461bcd60e51b815260040161061b90612233565b60405180910390fd5b60175460ff16156106475760405162461bcd60e51b815260040161061b906122e3565b601055565b60606000805461065b906123c1565b80601f0160208091040260200160405190810160405280929190818152602001828054610687906123c1565b80156106d45780601f106106a9576101008083540402835291602001916106d4565b820191906000526020600020905b8154815290600101906020018083116106b757829003601f168201915b5050505050905090565b60006106e982611572565b61074a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161061b565b506000908152600460205260409020546001600160a01b031690565b3361076f61108a565b6001600160a01b0316146107955760405162461bcd60e51b815260040161061b90612233565b60175460ff16156107b85760405162461bcd60e51b815260040161061b906122e3565b600f55565b60006107c882610c3c565b9050806001600160a01b0316836001600160a01b031614156108365760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161061b565b336001600160a01b0382161480610852575061085281336113b9565b6108bf5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b606482015260840161061b565b6108c9838361158f565b505050565b6108d833826115fd565b6108f45760405162461bcd60e51b815260040161061b90612268565b6108c98383836116c7565b3361090861108a565b6001600160a01b03161461092e5760405162461bcd60e51b815260040161061b90612233565b60175460ff16156109515760405162461bcd60e51b815260040161061b906122e3565b600d55565b600061096183610f71565b82106109c35760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161061b565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b336109f561108a565b6001600160a01b031614610a1b5760405162461bcd60e51b815260040161061b90612233565b601280546001600160a01b0319166001600160a01b0392909216919091179055565b6108c983838360405180602001604052806000815250611169565b6060610a6382611572565b610a7f5760405162461bcd60e51b815260040161061b906122b9565b601354600083815260156020526040908190205490516304a9bd7d60e21b81526001600160a01b03909216916312a6f5f491610ac19160040190815260200190565b60006040518083038186803b158015610ad957600080fd5b505afa158015610aed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105e691908101906120d6565b6000610b2060085490565b8210610b835760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161061b565b60088281548110610b9657610b96612443565b90600052602060002001549050919050565b60008080808080808080610bbd436001612366565b9050600d548110610bd857600d541515985060009650610bed565b6000985080600d54610bea919061237e565b96505b600e54610c0d5760009750610c0181611860565b91975095509350610c27565b60019750610c1c600e54611860565b509096509450600093505b6008549250600b549150509091929394959697565b6000818152600260205260408120546001600160a01b0316806105e65760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b606482015260840161061b565b600080600d54118015610cc85750600d544310155b610d115760405162461bcd60e51b815260206004820152601a602482015279185d58dd1a5bdb881a185cdb89dd081cdd185c9d1959081e595d60321b604482015260640161061b565b6000610d1c60085490565b9050600081600b54610d2e919061237e565b9050600c54811180610d635750600081118015610d635750610d4e61108a565b6001600160a01b0316336001600160a01b0316145b610daf5760405162461bcd60e51b815260206004820152601d60248201527f6d617820746f6b656e20696e766f636174696f6e732072656163686564000000604482015260640161061b565b600e54439015610dc25750600e54610ddc565b600c54610dd0906001612366565b821415610ddc5743600e555b600080610de883611860565b509092509050348114610e385760405162461bcd60e51b81526020600482015260186024820152771d985b1d5948191bd95cdb89dd08195c5d585b0818dbdcdd60421b604482015260640161061b565b6012546040516000916001600160a01b03169034908381818185875af1925050503d8060008114610e85576040519150601f19603f3d011682016040523d82523d6000602084013e610e8a565b606091505b5050905080610ece5760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b604482015260640161061b565b859650600087600143610ee1919061237e565b4060008a11610ef1576000610f10565b60156000610f0060018d61237e565b8152602001908152602001600020545b604080516020810194909452830191909152606082015260800160408051601f19818403018152918152815160209283012060008b815260158452828120829055601690935291208590559050610f67338961194f565b5050505050505090565b60006001600160a01b038216610fdc5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161061b565b506001600160a01b031660009081526003602052604090205490565b3361100161108a565b6001600160a01b0316146110275760405162461bcd60e51b815260040161061b90612233565b611031600061196d565b565b3361103c61108a565b6001600160a01b0316146110625760405162461bcd60e51b815260040161061b90612233565b60175460ff16156110855760405162461bcd60e51b815260040161061b906122e3565b600c55565b600a546001600160a01b031690565b60606001805461065b906123c1565b6001600160a01b0382163314156110fd5760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b604482015260640161061b565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61117333836115fd565b61118f5760405162461bcd60e51b815260040161061b90612268565b61119b848484846119bf565b50505050565b336111aa61108a565b6001600160a01b0316146111d05760405162461bcd60e51b815260040161061b90612233565b60175460ff16156111f35760405162461bcd60e51b815260040161061b906122e3565b601380546001600160a01b0319166001600160a01b0392909216919091179055565b3361121e61108a565b6001600160a01b0316146112445760405162461bcd60e51b815260040161061b90612233565b60175460ff16156112675760405162461bcd60e51b815260040161061b906122e3565b601155565b606061127782611572565b6112935760405162461bcd60e51b815260040161061b906122b9565b6014546000838152601560209081526040808320546016909252909120546001600160a01b0390921691637e99d4f29185916112ce836119f2565b6040516001600160e01b031960e087901b16815260048101949094526024840192909252604483015215156064820152608401610ac1565b606061131182611572565b61132d5760405162461bcd60e51b815260040161061b906122b9565b6014546000838152601560209081526040808320546016909252909120546001600160a01b0390921691633e47894a9185916112ce836119f2565b3361137161108a565b6001600160a01b0316146113975760405162461bcd60e51b815260040161061b90612233565b601480546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b336113f061108a565b6001600160a01b0316146114165760405162461bcd60e51b815260040161061b90612233565b60175460ff16156114395760405162461bcd60e51b815260040161061b906122e3565b600b55565b3361144761108a565b6001600160a01b03161461146d5760405162461bcd60e51b815260040161061b90612233565b6001600160a01b0381166114d25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161061b565b6114db8161196d565b50565b336114e761108a565b6001600160a01b03161461150d5760405162461bcd60e51b815260040161061b90612233565b6017805460ff19166001179055565b3b151590565b60006001600160e01b031982166380ac58cd60e01b148061155357506001600160e01b03198216635b5e139f60e01b145b806105e657506301ffc9a760e01b6001600160e01b03198316146105e6565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906115c482610c3c565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061160882611572565b6116695760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161061b565b600061167483610c3c565b9050806001600160a01b0316846001600160a01b031614806116af5750836001600160a01b03166116a4846106de565b6001600160a01b0316145b806116bf57506116bf81856113b9565b949350505050565b826001600160a01b03166116da82610c3c565b6001600160a01b0316146117425760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161061b565b6001600160a01b0382166117a45760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161061b565b6117af838383611a3d565b6117ba60008261158f565b6001600160a01b03831660009081526003602052604081208054600192906117e390849061237e565b90915550506001600160a01b0382166000908152600360205260408120805460019290611811908490612366565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03868116918217909255915184939187169160008051602061249b83398151915291a4505050565b6000806000600d546000141561187f575050600f546000915081611948565b600d548410156118ba576000601054600d5461189b9190612366565b90506000600f5486836118ae919061237e565b93509350935050611948565b600f54601054600d54600092919083906118d5908390612366565b905060005b60115481101561193a57818910156119085784846118f88b8561237e565b9750975097505050505050611948565b611911856123fc565b9450600193841c939290921b916119288383612366565b9150611933816123fc565b90506118da565b509295509093506000925050505b9193909250565b611969828260405180602001604052806000815250611af5565b5050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6119ca8484846116c7565b6119d684848484611b28565b61119b5760405162461bcd60e51b815260040161061b906121e1565b60008115611a355760166000611a0960018561237e565b815260200190815260200160002054601660008481526020019081526020016000205414159050919050565b506001919050565b6001600160a01b038316611a9857611a9381600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b611abb565b816001600160a01b0316836001600160a01b031614611abb57611abb8382611c35565b6001600160a01b038216611ad2576108c981611cd2565b826001600160a01b0316826001600160a01b0316146108c9576108c98282611d81565b611aff8383611dc5565b611b0c6000848484611b28565b6108c95760405162461bcd60e51b815260040161061b906121e1565b60006001600160a01b0384163b15611c2a57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611b6c903390899088908890600401612191565b602060405180830381600087803b158015611b8657600080fd5b505af1925050508015611bb6575060408051601f3d908101601f19168201909252611bb3918101906120b9565b60015b611c10573d808015611be4576040519150601f19603f3d011682016040523d82523d6000602084013e611be9565b606091505b508051611c085760405162461bcd60e51b815260040161061b906121e1565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506116bf565b506001949350505050565b60006001611c4284610f71565b611c4c919061237e565b600083815260076020526040902054909150808214611c9f576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090611ce49060019061237e565b60008381526009602052604081205460088054939450909284908110611d0c57611d0c612443565b906000526020600020015490508060088381548110611d2d57611d2d612443565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480611d6557611d6561242d565b6001900381819060005260206000200160009055905550505050565b6000611d8c83610f71565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b038216611e1b5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161061b565b611e2481611572565b15611e705760405162461bcd60e51b815260206004820152601c60248201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b604482015260640161061b565b611e7c60008383611a3d565b6001600160a01b0382166000908152600360205260408120805460019290611ea5908490612366565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b038616908117909155905183929060008051602061249b833981519152908290a45050565b600060208284031215611f0357600080fd5b8135611f0e8161246f565b9392505050565b60008060408385031215611f2857600080fd5b8235611f338161246f565b91506020830135611f438161246f565b809150509250929050565b600080600060608486031215611f6357600080fd5b8335611f6e8161246f565b92506020840135611f7e8161246f565b929592945050506040919091013590565b60008060008060808587031215611fa557600080fd5b8435611fb08161246f565b93506020850135611fc08161246f565b92506040850135915060608501356001600160401b03811115611fe257600080fd5b8501601f81018713611ff357600080fd5b80356120066120018261233f565b61230f565b81815288602083850101111561201b57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b6000806040838503121561205057600080fd5b823561205b8161246f565b915060208301358015158114611f4357600080fd5b6000806040838503121561208357600080fd5b823561208e8161246f565b946020939093013593505050565b6000602082840312156120ae57600080fd5b8135611f0e81612484565b6000602082840312156120cb57600080fd5b8151611f0e81612484565b6000602082840312156120e857600080fd5b81516001600160401b038111156120fe57600080fd5b8201601f8101841361210f57600080fd5b805161211d6120018261233f565b81815285602083850101111561213257600080fd5b612143826020830160208601612395565b95945050505050565b60006020828403121561215e57600080fd5b5035919050565b6000815180845261217d816020860160208601612395565b601f01601f19169290920160200192915050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906121c490830184612165565b9695505050505050565b602081526000611f0e6020830184612165565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60208082526010908201526f1d1bdad95b881b9bdd081b5a5b9d195960821b604082015260600190565b60208082526012908201527110dbdb9d1c9858dd081a5cc81b1bd8dad95960721b604082015260600190565b604051601f8201601f191681016001600160401b038111828210171561233757612337612459565b604052919050565b60006001600160401b0382111561235857612358612459565b50601f01601f191660200190565b6000821982111561237957612379612417565b500190565b60008282101561239057612390612417565b500390565b60005b838110156123b0578181015183820152602001612398565b8381111561119b5750506000910152565b600181811c908216806123d557607f821691505b602082108114156123f657634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561241057612410612417565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146114db57600080fd5b6001600160e01b0319811681146114db57600080fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122090b21747925068e2b95a809dfd2235f6a2462418c2d9737be1b7237b1f8bdc7764736f6c63430008060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003782dace9d900000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000040519d946311449b33d6b03bb40892faeef12d75000000000000000000000000bd9aa94b28e6362fc610d485ce779ef6baa041aa000000000000000000000000f8ee8798f1fbd48f95ca70d2a68fdda404660b550000000000000000000000000000000000000000000000000000000000000006437970686572000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044350485200000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : args (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
-----Encoded View---------------
16 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [2] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000400
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [6] : 00000000000000000000000000000000000000000000003782dace9d90000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [8] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [9] : 00000000000000000000000040519d946311449b33d6b03bb40892faeef12d75
Arg [10] : 000000000000000000000000bd9aa94b28e6362fc610d485ce779ef6baa041aa
Arg [11] : 000000000000000000000000f8ee8798f1fbd48f95ca70d2a68fdda404660b55
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [13] : 4379706865720000000000000000000000000000000000000000000000000000
Arg [14] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [15] : 4350485200000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
89593:8303:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36263:224;;;;;;;;;;-1:-1:-1;36263:224:0;;;;;:::i;:::-;;:::i;:::-;;;6675:14:1;;6668:22;6650:41;;6638:2;6623:18;36263:224:0;;;;;;;;92161:148;;;;;;;;;;-1:-1:-1;92161:148:0;;;;;:::i;:::-;;:::i;:::-;;23389:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;24948:221::-;;;;;;;;;;-1:-1:-1;24948:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;5973:32:1;;;5955:51;;5943:2;5928:18;24948:221:0;5910:102:1;92025:128:0;;;;;;;;;;-1:-1:-1;92025:128:0;;;;;:::i;:::-;;:::i;24471:411::-;;;;;;;;;;-1:-1:-1;24471:411:0;;;;;:::i;:::-;;:::i;36903:113::-;;;;;;;;;;-1:-1:-1;36991:10:0;:17;36903:113;;;7552:25:1;;;7540:2;7525:18;36903:113:0;7507:76:1;25838:339:0;;;;;;;;;;-1:-1:-1;25838:339:0;;;;;:::i;:::-;;:::i;91861:156::-;;;;;;;;;;-1:-1:-1;91861:156:0;;;;;:::i;:::-;;:::i;36571:256::-;;;;;;;;;;-1:-1:-1;36571:256:0;;;;;:::i;:::-;;:::i;92457:121::-;;;;;;;;;;-1:-1:-1;92457:121:0;;;;;:::i;:::-;;:::i;26248:185::-;;;;;;;;;;-1:-1:-1;26248:185:0;;;;;:::i;:::-;;:::i;96006:204::-;;;;;;;;;;-1:-1:-1;96006:204:0;;;;;:::i;:::-;;:::i;37093:233::-;;;;;;;;;;-1:-1:-1;37093:233:0;;;;;:::i;:::-;;:::i;92848:1256::-;;;;;;;;;;;;;:::i;:::-;;;;7058:14:1;;7051:22;7033:41;;7117:14;;7110:22;7105:2;7090:18;;7083:50;7149:18;;;7142:34;;;;7207:2;7192:18;;7185:34;;;;7250:3;7235:19;;7228:35;7294:3;7279:19;;7272:35;7338:3;7323:19;;7316:35;7382:3;7367:19;;7360:35;7020:3;7005:19;92848:1256:0;6987:414:1;23083:239:0;;;;;;;;;;-1:-1:-1;23083:239:0;;;;;:::i;:::-;;:::i;94112:1550::-;;;:::i;22813:208::-;;;;;;;;;;-1:-1:-1;22813:208:0;;;;;:::i;:::-;;:::i;3001:94::-;;;;;;;;;;;;;:::i;91689:164::-;;;;;;;;;;-1:-1:-1;91689:164:0;;;;;:::i;:::-;;:::i;2350:87::-;;;;;;;;;;;;;:::i;23558:104::-;;;;;;;;;;;;;:::i;25241:295::-;;;;;;;;;;-1:-1:-1;25241:295:0;;;;;:::i;:::-;;:::i;26504:328::-;;;;;;;;;;-1:-1:-1;26504:328:0;;;;;:::i;:::-;;:::i;92586:130::-;;;;;;;;;;-1:-1:-1;92586:130:0;;;;;:::i;:::-;;:::i;92317:132::-;;;;;;;;;;-1:-1:-1;92317:132:0;;;;;:::i;:::-;;:::i;96218:345::-;;;;;;;;;;-1:-1:-1;96218:345:0;;;;;:::i;:::-;;:::i;95671:327::-;;;;;;;;;;-1:-1:-1;95671:327:0;;;;;:::i;:::-;;:::i;92724:116::-;;;;;;;;;;-1:-1:-1;92724:116:0;;;;;:::i;:::-;;:::i;25607:164::-;;;;;;;;;;-1:-1:-1;25607:164:0;;;;;:::i;:::-;;:::i;91517:::-;;;;;;;;;;-1:-1:-1;91517:164:0;;;;;:::i;:::-;;:::i;3250:192::-;;;;;;;;;;-1:-1:-1;3250:192:0;;;;;:::i;:::-;;:::i;91436:73::-;;;;;;;;;;;;;:::i;36263:224::-;36365:4;-1:-1:-1;;;;;;36389:50:0;;-1:-1:-1;;;36389:50:0;;:90;;;36443:36;36467:11;36443:23;:36::i;:::-;36382:97;36263:224;-1:-1:-1;;36263:224:0:o;92161:148::-;1304:10;2570:7;:5;:7::i;:::-;-1:-1:-1;;;;;2570:23:0;;2562:68;;;;-1:-1:-1;;;2562:68:0;;;;;;;:::i;:::-;;;;;;;;;91376:9:::1;::::0;::::1;;91375:10;91367:41;;;;-1:-1:-1::0;;;91367:41:0::1;;;;;;;:::i;:::-;92267:16:::2;:34:::0;92161:148::o;23389:100::-;23443:13;23476:5;23469:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23389:100;:::o;24948:221::-;25024:7;25052:16;25060:7;25052;:16::i;:::-;25044:73;;;;-1:-1:-1;;;25044:73:0;;13099:2:1;25044:73:0;;;13081:21:1;13138:2;13118:18;;;13111:30;13177:34;13157:18;;;13150:62;-1:-1:-1;;;13228:18:1;;;13221:42;13280:19;;25044:73:0;13071:234:1;25044:73:0;-1:-1:-1;25137:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;25137:24:0;;24948:221::o;92025:128::-;1304:10;2570:7;:5;:7::i;:::-;-1:-1:-1;;;;;2570:23:0;;2562:68;;;;-1:-1:-1;;;2562:68:0;;;;;;;:::i;:::-;91376:9:::1;::::0;::::1;;91375:10;91367:41;;;;-1:-1:-1::0;;;91367:41:0::1;;;;;;;:::i;:::-;92121:11:::2;:24:::0;92025:128::o;24471:411::-;24552:13;24568:23;24583:7;24568:14;:23::i;:::-;24552:39;;24616:5;-1:-1:-1;;;;;24610:11:0;:2;-1:-1:-1;;;;;24610:11:0;;;24602:57;;;;-1:-1:-1;;;24602:57:0;;14638:2:1;24602:57:0;;;14620:21:1;14677:2;14657:18;;;14650:30;14716:34;14696:18;;;14689:62;-1:-1:-1;;;14767:18:1;;;14760:31;14808:19;;24602:57:0;14610:223:1;24602:57:0;1304:10;-1:-1:-1;;;;;24694:21:0;;;;:62;;-1:-1:-1;24719:37:0;24736:5;1304:10;25607:164;:::i;24719:37::-;24672:168;;;;-1:-1:-1;;;24672:168:0;;11492:2:1;24672:168:0;;;11474:21:1;11531:2;11511:18;;;11504:30;11570:34;11550:18;;;11543:62;-1:-1:-1;;;11621:18:1;;;11614:54;11685:19;;24672:168:0;11464:246:1;24672:168:0;24853:21;24862:2;24866:7;24853:8;:21::i;:::-;24541:341;24471:411;;:::o;25838:339::-;26033:41;1304:10;26066:7;26033:18;:41::i;:::-;26025:103;;;;-1:-1:-1;;;26025:103:0;;;;;;;:::i;:::-;26141:28;26151:4;26157:2;26161:7;26141:9;:28::i;91861:156::-;1304:10;2570:7;:5;:7::i;:::-;-1:-1:-1;;;;;2570:23:0;;2562:68;;;;-1:-1:-1;;;2562:68:0;;;;;;;:::i;:::-;91376:9:::1;::::0;::::1;;91375:10;91367:41;;;;-1:-1:-1::0;;;91367:41:0::1;;;;;;;:::i;:::-;91971:18:::2;:38:::0;91861:156::o;36571:256::-;36668:7;36704:23;36721:5;36704:16;:23::i;:::-;36696:5;:31;36688:87;;;;-1:-1:-1;;;36688:87:0;;8014:2:1;36688:87:0;;;7996:21:1;8053:2;8033:18;;;8026:30;8092:34;8072:18;;;8065:62;-1:-1:-1;;;8143:18:1;;;8136:41;8194:19;;36688:87:0;7986:233:1;36688:87:0;-1:-1:-1;;;;;;36793:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;36571:256::o;92457:121::-;1304:10;2570:7;:5;:7::i;:::-;-1:-1:-1;;;;;2570:23:0;;2562:68;;;;-1:-1:-1;;;2562:68:0;;;;;;;:::i;:::-;92548:10:::1;:22:::0;;-1:-1:-1;;;;;;92548:22:0::1;-1:-1:-1::0;;;;;92548:22:0;;;::::1;::::0;;;::::1;::::0;;92457:121::o;26248:185::-;26386:39;26403:4;26409:2;26413:7;26386:39;;;;;;;;;;;;:16;:39::i;96006:204::-;96072:13;96112:16;96120:7;96112;:16::i;:::-;96104:45;;;;-1:-1:-1;;;96104:45:0;;;;;;;:::i;:::-;96167:8;;;96185:16;;;:7;:16;;;;;;;;96167:35;;-1:-1:-1;;;96167:35:0;;-1:-1:-1;;;;;96167:8:0;;;;:17;;:35;;;;7552:25:1;;;7540:2;7525:18;;7507:76;96167:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;96167:35:0;;;;;;;;;;;;:::i;37093:233::-;37168:7;37204:30;36991:10;:17;;36903:113;37204:30;37196:5;:38;37188:95;;;;-1:-1:-1;;;37188:95:0;;16148:2:1;37188:95:0;;;16130:21:1;16187:2;16167:18;;;16160:30;16226:34;16206:18;;;16199:62;-1:-1:-1;;;16277:18:1;;;16270:42;16329:19;;37188:95:0;16120:234:1;37188:95:0;37301:10;37312:5;37301:17;;;;;;;;:::i;:::-;;;;;;;;;37294:24;;37093:233;;;:::o;92848:1256::-;92910:15;;;;;;;;;93242:16;:12;93257:1;93242:16;:::i;:::-;93222:36;;93286:18;;93273:9;:31;93269:295;;93343:18;;:23;;;-1:-1:-1;93365:1:0;;-1:-1:-1;93269:295:0;;;93474:5;93461:18;;93543:9;93522:18;;:30;;;;:::i;:::-;93496:56;;93269:295;93580:16;;93576:417;;93638:5;93627:16;;93746:27;93763:9;93746:16;:27::i;:::-;93660:113;;-1:-1:-1;93660:113:0;-1:-1:-1;93660:113:0;-1:-1:-1;93576:417:0;;;93835:4;93824:15;;93906:34;93923:16;;93906;:34::i;:::-;-1:-1:-1;93856:84:0;;-1:-1:-1;93856:84:0;-1:-1:-1;93980:1:0;;-1:-1:-1;93576:417:0;36991:10;:17;94005:38;;94076:20;;94054:42;;93211:893;92848:1256;;;;;;;;:::o;23083:239::-;23155:7;23191:16;;;:7;:16;;;;;;-1:-1:-1;;;;;23191:16:0;23226:19;23218:73;;;;-1:-1:-1;;;23218:73:0;;12328:2:1;23218:73:0;;;12310:21:1;12367:2;12347:18;;;12340:30;12406:34;12386:18;;;12379:62;-1:-1:-1;;;12457:18:1;;;12450:39;12506:19;;23218:73:0;12300:231:1;94112:1550:0;94166:15;94228:1;94207:18;;:22;:60;;;;;94249:18;;94233:12;:34;;94207:60;94199:117;;;;-1:-1:-1;;;94199:117:0;;13873:2:1;94199:117:0;;;13855:21:1;13912:2;13892:18;;;13885:30;-1:-1:-1;;;13931:18:1;;;13924:56;13997:18;;94199:117:0;13845:176:1;94199:117:0;94329:24;94356:13;36991:10;:17;;36903:113;94356:13;94329:40;;94380:28;94434:16;94411:20;;:39;;;;:::i;:::-;94380:70;;94502:20;;94479;:43;:111;;;;94563:1;94540:20;:24;:49;;;;;94582:7;:5;:7::i;:::-;-1:-1:-1;;;;;94568:21:0;:10;-1:-1:-1;;;;;94568:21:0;;94540:49;94471:167;;;;-1:-1:-1;;;94471:167:0;;9609:2:1;94471:167:0;;;9591:21:1;9648:2;9628:18;;;9621:30;9687:31;9667:18;;;9660:59;9736:18;;94471:167:0;9581:179:1;94471:167:0;94700:16;;94673:12;;94700:21;94696:231;;-1:-1:-1;94761:16:0;;94696:231;;;94833:20;;:24;;94856:1;94833:24;:::i;:::-;94808:20;:50;94804:123;;;94903:12;94884:16;:31;94804:123;94939:18;94968:11;95012:29;95029:11;95012:16;:29::i;:::-;-1:-1:-1;94990:51:0;;-1:-1:-1;94990:51:0;-1:-1:-1;95062:9:0;:16;;95054:53;;;;-1:-1:-1;;;95054:53:0;;10726:2:1;95054:53:0;;;10708:21:1;10765:2;10745:18;;;10738:30;-1:-1:-1;;;10784:18:1;;;10777:54;10848:18;;95054:53:0;10698:174:1;95054:53:0;95147:10;;:36;;95129:12;;-1:-1:-1;;;;;95147:10:0;;95169:9;;95129:12;95147:36;95129:12;95147:36;95169:9;95147:10;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95128:55;;;95202:7;95194:36;;;;-1:-1:-1;;;95194:36:0;;15040:2:1;95194:36:0;;;15022:21:1;15079:2;15059:18;;;15052:30;-1:-1:-1;;;15098:18:1;;;15091:46;15154:18;;95194:36:0;15012:166:1;95194:36:0;95261:16;95251:26;;95288:12;95344:7;95408:1;95393:12;:16;;;;:::i;:::-;95383:27;95451:1;95441:7;:11;:47;;95486:1;95441:47;;;95455:7;:20;95463:11;95473:1;95463:7;:11;:::i;:::-;95455:20;;;;;;;;;;;;95441:47;95327:162;;;;;;5677:19:1;;;;5712:12;;5705:28;;;;5749:12;;;5742:28;5786:12;;95327:162:0;;;-1:-1:-1;;95327:162:0;;;;;;;;;95303:187;;95327:162;95303:187;;;;95511:16;;;;:7;:16;;;;;:23;;;95545:11;:20;;;;;:33;;;95303:187;-1:-1:-1;95589:30:0;95599:10;95519:7;95589:9;:30::i;:::-;95640:14;;;;;;;94112:1550;:::o;22813:208::-;22885:7;-1:-1:-1;;;;;22913:19:0;;22905:74;;;;-1:-1:-1;;;22905:74:0;;11917:2:1;22905:74:0;;;11899:21:1;11956:2;11936:18;;;11929:30;11995:34;11975:18;;;11968:62;-1:-1:-1;;;12046:18:1;;;12039:40;12096:19;;22905:74:0;11889:232:1;22905:74:0;-1:-1:-1;;;;;;22997:16:0;;;;;:9;:16;;;;;;;22813:208::o;3001:94::-;1304:10;2570:7;:5;:7::i;:::-;-1:-1:-1;;;;;2570:23:0;;2562:68;;;;-1:-1:-1;;;2562:68:0;;;;;;;:::i;:::-;3066:21:::1;3084:1;3066:9;:21::i;:::-;3001:94::o:0;91689:164::-;1304:10;2570:7;:5;:7::i;:::-;-1:-1:-1;;;;;2570:23:0;;2562:68;;;;-1:-1:-1;;;2562:68:0;;;;;;;:::i;:::-;91376:9:::1;::::0;::::1;;91375:10;91367:41;;;;-1:-1:-1::0;;;91367:41:0::1;;;;;;;:::i;:::-;91803:20:::2;:42:::0;91689:164::o;2350:87::-;2423:6;;-1:-1:-1;;;;;2423:6:0;;2350:87::o;23558:104::-;23614:13;23647:7;23640:14;;;;;:::i;25241:295::-;-1:-1:-1;;;;;25344:24:0;;1304:10;25344:24;;25336:62;;;;-1:-1:-1;;;25336:62:0;;10372:2:1;25336:62:0;;;10354:21:1;10411:2;10391:18;;;10384:30;-1:-1:-1;;;10430:18:1;;;10423:55;10495:18;;25336:62:0;10344:175:1;25336:62:0;1304:10;25411:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;25411:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;25411:53:0;;;;;;;;;;25480:48;;6650:41:1;;;25411:42:0;;1304:10;25480:48;;6623:18:1;25480:48:0;;;;;;;25241:295;;:::o;26504:328::-;26679:41;1304:10;26712:7;26679:18;:41::i;:::-;26671:103;;;;-1:-1:-1;;;26671:103:0;;;;;;;:::i;:::-;26785:39;26799:4;26805:2;26809:7;26818:5;26785:13;:39::i;:::-;26504:328;;;;:::o;92586:130::-;1304:10;2570:7;:5;:7::i;:::-;-1:-1:-1;;;;;2570:23:0;;2562:68;;;;-1:-1:-1;;;2562:68:0;;;;;;;:::i;:::-;91376:9:::1;::::0;::::1;;91375:10;91367:41;;;;-1:-1:-1::0;;;91367:41:0::1;;;;;;;:::i;:::-;92690:8:::2;:18:::0;;-1:-1:-1;;;;;;92690:18:0::2;-1:-1:-1::0;;;;;92690:18:0;;;::::2;::::0;;;::::2;::::0;;92586:130::o;92317:132::-;1304:10;2570:7;:5;:7::i;:::-;-1:-1:-1;;;;;2570:23:0;;2562:68;;;;-1:-1:-1;;;2562:68:0;;;;;;;:::i;:::-;91376:9:::1;::::0;::::1;;91375:10;91367:41;;;;-1:-1:-1::0;;;91367:41:0::1;;;;;;;:::i;:::-;92415:12:::2;:26:::0;92317:132::o;96218:345::-;96301:13;96341:16;96349:7;96341;:16::i;:::-;96333:45;;;;-1:-1:-1;;;96333:45:0;;;;;;;:::i;:::-;96398:9;;;96454:16;;;:7;:16;;;;;;;;;96485:11;:20;;;;;;;-1:-1:-1;;;;;96398:9:0;;;;:18;;96431:7;;96520:34;96431:7;96520:25;:34::i;:::-;96398:157;;-1:-1:-1;;;;;;96398:157:0;;;;;;;;;;17113:25:1;;;;17154:18;;;17147:34;;;;17197:18;;;17190:34;17267:14;17260:22;17240:18;;;17233:50;17085:19;;96398:157:0;17067:222:1;95671:327:0;95736:13;95775:16;95783:7;95775;:16::i;:::-;95767:45;;;;-1:-1:-1;;;95767:45:0;;;;;;;:::i;:::-;95832:9;;;95889:16;;;:7;:16;;;;;;;;;95920:11;:20;;;;;;;-1:-1:-1;;;;;95832:9:0;;;;:18;;95866:7;;95955:34;95866:7;95955:25;:34::i;92724:116::-;1304:10;2570:7;:5;:7::i;:::-;-1:-1:-1;;;;;2570:23:0;;2562:68;;;;-1:-1:-1;;;2562:68:0;;;;;;;:::i;:::-;92816:9:::1;:16:::0;;-1:-1:-1;;;;;;92816:16:0::1;-1:-1:-1::0;;;;;92816:16:0;;;::::1;::::0;;;::::1;::::0;;92724:116::o;25607:164::-;-1:-1:-1;;;;;25728:25:0;;;25704:4;25728:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;25607:164::o;91517:::-;1304:10;2570:7;:5;:7::i;:::-;-1:-1:-1;;;;;2570:23:0;;2562:68;;;;-1:-1:-1;;;2562:68:0;;;;;;;:::i;:::-;91376:9:::1;::::0;::::1;;91375:10;91367:41;;;;-1:-1:-1::0;;;91367:41:0::1;;;;;;;:::i;:::-;91631:20:::2;:42:::0;91517:164::o;3250:192::-;1304:10;2570:7;:5;:7::i;:::-;-1:-1:-1;;;;;2570:23:0;;2562:68;;;;-1:-1:-1;;;2562:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;3339:22:0;::::1;3331:73;;;::::0;-1:-1:-1;;;3331:73:0;;8845:2:1;3331:73:0::1;::::0;::::1;8827:21:1::0;8884:2;8864:18;;;8857:30;8923:34;8903:18;;;8896:62;-1:-1:-1;;;8974:18:1;;;8967:36;9020:19;;3331:73:0::1;8817:228:1::0;3331:73:0::1;3415:19;3425:8;3415:9;:19::i;:::-;3250:192:::0;:::o;91436:73::-;1304:10;2570:7;:5;:7::i;:::-;-1:-1:-1;;;;;2570:23:0;;2562:68;;;;-1:-1:-1;;;2562:68:0;;;;;;;:::i;:::-;91485:9:::1;:16:::0;;-1:-1:-1;;91485:16:0::1;91497:4;91485:16;::::0;;91436:73::o;12112:387::-;12435:20;12483:8;;;12112:387::o;22444:305::-;22546:4;-1:-1:-1;;;;;;22583:40:0;;-1:-1:-1;;;22583:40:0;;:105;;-1:-1:-1;;;;;;;22640:48:0;;-1:-1:-1;;;22640:48:0;22583:105;:158;;;-1:-1:-1;;;;;;;;;;9896:40:0;;;22705:36;9787:157;28342:127;28407:4;28431:16;;;:7;:16;;;;;;-1:-1:-1;;;;;28431:16:0;:30;;;28342:127::o;32324:174::-;32399:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;32399:29:0;-1:-1:-1;;;;;32399:29:0;;;;;;;;:24;;32453:23;32399:24;32453:14;:23::i;:::-;-1:-1:-1;;;;;32444:46:0;;;;;;;;;;;32324:174;;:::o;28636:348::-;28729:4;28754:16;28762:7;28754;:16::i;:::-;28746:73;;;;-1:-1:-1;;;28746:73:0;;11079:2:1;28746:73:0;;;11061:21:1;11118:2;11098:18;;;11091:30;11157:34;11137:18;;;11130:62;-1:-1:-1;;;11208:18:1;;;11201:42;11260:19;;28746:73:0;11051:234:1;28746:73:0;28830:13;28846:23;28861:7;28846:14;:23::i;:::-;28830:39;;28899:5;-1:-1:-1;;;;;28888:16:0;:7;-1:-1:-1;;;;;28888:16:0;;:51;;;;28932:7;-1:-1:-1;;;;;28908:31:0;:20;28920:7;28908:11;:20::i;:::-;-1:-1:-1;;;;;28908:31:0;;28888:51;:87;;;;28943:32;28960:5;28967:7;28943:16;:32::i;:::-;28880:96;28636:348;-1:-1:-1;;;;28636:348:0:o;31628:578::-;31787:4;-1:-1:-1;;;;;31760:31:0;:23;31775:7;31760:14;:23::i;:::-;-1:-1:-1;;;;;31760:31:0;;31752:85;;;;-1:-1:-1;;;31752:85:0;;14228:2:1;31752:85:0;;;14210:21:1;14267:2;14247:18;;;14240:30;14306:34;14286:18;;;14279:62;-1:-1:-1;;;14357:18:1;;;14350:39;14406:19;;31752:85:0;14200:231:1;31752:85:0;-1:-1:-1;;;;;31856:16:0;;31848:65;;;;-1:-1:-1;;;31848:65:0;;9967:2:1;31848:65:0;;;9949:21:1;10006:2;9986:18;;;9979:30;10045:34;10025:18;;;10018:62;-1:-1:-1;;;10096:18:1;;;10089:34;10140:19;;31848:65:0;9939:226:1;31848:65:0;31926:39;31947:4;31953:2;31957:7;31926:20;:39::i;:::-;32030:29;32047:1;32051:7;32030:8;:29::i;:::-;-1:-1:-1;;;;;32072:15:0;;;;;;:9;:15;;;;;:20;;32091:1;;32072:15;:20;;32091:1;;32072:20;:::i;:::-;;;;-1:-1:-1;;;;;;;32103:13:0;;;;;;:9;:13;;;;;:18;;32120:1;;32103:13;:18;;32120:1;;32103:18;:::i;:::-;;;;-1:-1:-1;;32132:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;32132:21:0;-1:-1:-1;;;;;32132:21:0;;;;;;;;;32171:27;;32132:16;;32171:27;;;;-1:-1:-1;;;;;;;;;;;32171:27:0;;31628:578;;;:::o;96571:1071::-;96650:25;96687:18;96717:30;96769:18;;96791:1;96769:23;96765:91;;;-1:-1:-1;;96829:11:0;;96826:1;;-1:-1:-1;96826:1:0;96818:26;;96765:91;96894:18;;96880:11;:32;96876:200;;;96938:20;96982:16;;96961:18;;:37;;;;:::i;:::-;96938:60;;97021:1;97024:11;;97052;97037:12;:26;;;;:::i;:::-;97013:51;;;;;;;;;96876:200;97135:11;;97176:16;;97225:18;;97088;;97135:11;97176:16;97088:18;;97225:29;;97176:16;;97225:29;:::i;:::-;97203:51;;97272:9;97267:328;97291:12;;97287:1;:16;97267:328;;;97352:11;97338;:25;97334:130;;;97405:10;97417:3;97422:25;97436:11;97422;:25;:::i;:::-;97397:51;;;;;;;;;;;;;97334:130;97480:12;;;:::i;:::-;;-1:-1:-1;97515:1:0;97507:9;;;;97531:14;;;;;97560:23;97531:14;97560:23;;:::i;:::-;;-1:-1:-1;97305:3:0;;;:::i;:::-;;;97267:328;;;-1:-1:-1;97615:10:0;;-1:-1:-1;97627:3:0;;-1:-1:-1;97632:1:0;;-1:-1:-1;;;96571:1071:0;;;;;;:::o;29326:110::-;29402:26;29412:2;29416:7;29402:26;;;;;;;;;;;;:9;:26::i;:::-;29326:110;;:::o;3450:173::-;3525:6;;;-1:-1:-1;;;;;3542:17:0;;;-1:-1:-1;;;;;;3542:17:0;;;;;;;3575:40;;3525:6;;;3542:17;3525:6;;3575:40;;3506:16;;3575:40;3495:128;3450:173;:::o;27714:315::-;27871:28;27881:4;27887:2;27891:7;27871:9;:28::i;:::-;27918:48;27941:4;27947:2;27951:7;27960:5;27918:22;:48::i;:::-;27910:111;;;;-1:-1:-1;;;27910:111:0;;;;;;;:::i;97650:243::-;97732:4;97758:11;;97754:108;;97826:11;:24;97838:11;97848:1;97838:7;:11;:::i;:::-;97826:24;;;;;;;;;;;;97802:11;:20;97814:7;97802:20;;;;;;;;;;;;:48;;97795:55;;97650:243;;;:::o;97754:108::-;-1:-1:-1;97881:4:0;;97650:243;-1:-1:-1;97650:243:0:o;37939:589::-;-1:-1:-1;;;;;38145:18:0;;38141:187;;38180:40;38212:7;39355:10;:17;;39328:24;;;;:15;:24;;;;;:44;;;39383:24;;;;;;;;;;;;39251:164;38180:40;38141:187;;;38250:2;-1:-1:-1;;;;;38242:10:0;:4;-1:-1:-1;;;;;38242:10:0;;38238:90;;38269:47;38302:4;38308:7;38269:32;:47::i;:::-;-1:-1:-1;;;;;38342:16:0;;38338:183;;38375:45;38412:7;38375:36;:45::i;38338:183::-;38448:4;-1:-1:-1;;;;;38442:10:0;:2;-1:-1:-1;;;;;38442:10:0;;38438:83;;38469:40;38497:2;38501:7;38469:27;:40::i;29663:321::-;29793:18;29799:2;29803:7;29793:5;:18::i;:::-;29844:54;29875:1;29879:2;29883:7;29892:5;29844:22;:54::i;:::-;29822:154;;;;-1:-1:-1;;;29822:154:0;;;;;;;:::i;33063:803::-;33218:4;-1:-1:-1;;;;;33239:13:0;;12435:20;12483:8;33235:624;;33275:72;;-1:-1:-1;;;33275:72:0;;-1:-1:-1;;;;;33275:36:0;;;;;:72;;1304:10;;33326:4;;33332:7;;33341:5;;33275:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33275:72:0;;;;;;;;-1:-1:-1;;33275:72:0;;;;;;;;;;;;:::i;:::-;;;33271:533;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33521:13:0;;33517:272;;33564:60;;-1:-1:-1;;;33564:60:0;;;;;;;:::i;33517:272::-;33739:6;33733:13;33724:6;33720:2;33716:15;33709:38;33271:533;-1:-1:-1;;;;;;33398:55:0;-1:-1:-1;;;33398:55:0;;-1:-1:-1;33391:62:0;;33235:624;-1:-1:-1;33843:4:0;33063:803;;;;;;:::o;40042:988::-;40308:22;40358:1;40333:22;40350:4;40333:16;:22::i;:::-;:26;;;;:::i;:::-;40370:18;40391:26;;;:17;:26;;;;;;40308:51;;-1:-1:-1;40524:28:0;;;40520:328;;-1:-1:-1;;;;;40591:18:0;;40569:19;40591:18;;;:12;:18;;;;;;;;:34;;;;;;;;;40642:30;;;;;;:44;;;40759:30;;:17;:30;;;;;:43;;;40520:328;-1:-1:-1;40944:26:0;;;;:17;:26;;;;;;;;40937:33;;;-1:-1:-1;;;;;40988:18:0;;;;;:12;:18;;;;;:34;;;;;;;40981:41;40042:988::o;41325:1079::-;41603:10;:17;41578:22;;41603:21;;41623:1;;41603:21;:::i;:::-;41635:18;41656:24;;;:15;:24;;;;;;42029:10;:26;;41578:46;;-1:-1:-1;41656:24:0;;41578:46;;42029:26;;;;;;:::i;:::-;;;;;;;;;42007:48;;42093:11;42068:10;42079;42068:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;42173:28;;;:15;:28;;;;;;;:41;;;42345:24;;;;;42338:31;42380:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;41396:1008;;;41325:1079;:::o;38829:221::-;38914:14;38931:20;38948:2;38931:16;:20::i;:::-;-1:-1:-1;;;;;38962:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;39007:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;38829:221:0:o;30320:382::-;-1:-1:-1;;;;;30400:16:0;;30392:61;;;;-1:-1:-1;;;30392:61:0;;12738:2:1;30392:61:0;;;12720:21:1;;;12757:18;;;12750:30;12816:34;12796:18;;;12789:62;12868:18;;30392:61:0;12710:182:1;30392:61:0;30473:16;30481:7;30473;:16::i;:::-;30472:17;30464:58;;;;-1:-1:-1;;;30464:58:0;;9252:2:1;30464:58:0;;;9234:21:1;9291:2;9271:18;;;9264:30;-1:-1:-1;;;9310:18:1;;;9303:58;9378:18;;30464:58:0;9224:178:1;30464:58:0;30535:45;30564:1;30568:2;30572:7;30535:20;:45::i;:::-;-1:-1:-1;;;;;30593:13:0;;;;;;:9;:13;;;;;:18;;30610:1;;30593:13;:18;;30610:1;;30593:18;:::i;:::-;;;;-1:-1:-1;;30622:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;30622:21:0;-1:-1:-1;;;;;30622:21:0;;;;;;;;30661:33;;30622:16;;;-1:-1:-1;;;;;;;;;;;30661:33:0;30622:16;;30661:33;30320:382;;:::o;14:247:1:-;73:6;126:2;114:9;105:7;101:23;97:32;94:2;;;142:1;139;132:12;94:2;181:9;168:23;200:31;225:5;200:31;:::i;:::-;250:5;84:177;-1:-1:-1;;;84:177:1:o;526:388::-;594:6;602;655:2;643:9;634:7;630:23;626:32;623:2;;;671:1;668;661:12;623:2;710:9;697:23;729:31;754:5;729:31;:::i;:::-;779:5;-1:-1:-1;836:2:1;821:18;;808:32;849:33;808:32;849:33;:::i;:::-;901:7;891:17;;;613:301;;;;;:::o;919:456::-;996:6;1004;1012;1065:2;1053:9;1044:7;1040:23;1036:32;1033:2;;;1081:1;1078;1071:12;1033:2;1120:9;1107:23;1139:31;1164:5;1139:31;:::i;:::-;1189:5;-1:-1:-1;1246:2:1;1231:18;;1218:32;1259:33;1218:32;1259:33;:::i;:::-;1023:352;;1311:7;;-1:-1:-1;;;1365:2:1;1350:18;;;;1337:32;;1023:352::o;1380:1016::-;1475:6;1483;1491;1499;1552:3;1540:9;1531:7;1527:23;1523:33;1520:2;;;1569:1;1566;1559:12;1520:2;1608:9;1595:23;1627:31;1652:5;1627:31;:::i;:::-;1677:5;-1:-1:-1;1734:2:1;1719:18;;1706:32;1747:33;1706:32;1747:33;:::i;:::-;1799:7;-1:-1:-1;1853:2:1;1838:18;;1825:32;;-1:-1:-1;1908:2:1;1893:18;;1880:32;-1:-1:-1;;;;;1924:30:1;;1921:2;;;1967:1;1964;1957:12;1921:2;1990:22;;2043:4;2035:13;;2031:27;-1:-1:-1;2021:2:1;;2072:1;2069;2062:12;2021:2;2108;2095:16;2133:48;2149:31;2177:2;2149:31;:::i;:::-;2133:48;:::i;:::-;2204:2;2197:5;2190:17;2244:7;2239:2;2234;2230;2226:11;2222:20;2219:33;2216:2;;;2265:1;2262;2255:12;2216:2;2320;2315;2311;2307:11;2302:2;2295:5;2291:14;2278:45;2364:1;2359:2;2354;2347:5;2343:14;2339:23;2332:34;2385:5;2375:15;;;;;1510:886;;;;;;;:::o;2401:416::-;2466:6;2474;2527:2;2515:9;2506:7;2502:23;2498:32;2495:2;;;2543:1;2540;2533:12;2495:2;2582:9;2569:23;2601:31;2626:5;2601:31;:::i;:::-;2651:5;-1:-1:-1;2708:2:1;2693:18;;2680:32;2750:15;;2743:23;2731:36;;2721:2;;2781:1;2778;2771:12;2822:315;2890:6;2898;2951:2;2939:9;2930:7;2926:23;2922:32;2919:2;;;2967:1;2964;2957:12;2919:2;3006:9;2993:23;3025:31;3050:5;3025:31;:::i;:::-;3075:5;3127:2;3112:18;;;;3099:32;;-1:-1:-1;;;2909:228:1:o;3142:245::-;3200:6;3253:2;3241:9;3232:7;3228:23;3224:32;3221:2;;;3269:1;3266;3259:12;3221:2;3308:9;3295:23;3327:30;3351:5;3327:30;:::i;3392:249::-;3461:6;3514:2;3502:9;3493:7;3489:23;3485:32;3482:2;;;3530:1;3527;3520:12;3482:2;3562:9;3556:16;3581:30;3605:5;3581:30;:::i;4195:635::-;4275:6;4328:2;4316:9;4307:7;4303:23;4299:32;4296:2;;;4344:1;4341;4334:12;4296:2;4371:16;;-1:-1:-1;;;;;4399:30:1;;4396:2;;;4442:1;4439;4432:12;4396:2;4465:22;;4518:4;4510:13;;4506:27;-1:-1:-1;4496:2:1;;4547:1;4544;4537:12;4496:2;4576;4570:9;4601:48;4617:31;4645:2;4617:31;:::i;4601:48::-;4672:2;4665:5;4658:17;4712:7;4707:2;4702;4698;4694:11;4690:20;4687:33;4684:2;;;4733:1;4730;4723:12;4684:2;4746:54;4797:2;4792;4785:5;4781:14;4776:2;4772;4768:11;4746:54;:::i;:::-;4819:5;4286:544;-1:-1:-1;;;;;4286:544:1:o;4835:180::-;4894:6;4947:2;4935:9;4926:7;4922:23;4918:32;4915:2;;;4963:1;4960;4953:12;4915:2;-1:-1:-1;4986:23:1;;4905:110;-1:-1:-1;4905:110:1:o;5020:257::-;5061:3;5099:5;5093:12;5126:6;5121:3;5114:19;5142:63;5198:6;5191:4;5186:3;5182:14;5175:4;5168:5;5164:16;5142:63;:::i;:::-;5259:2;5238:15;-1:-1:-1;;5234:29:1;5225:39;;;;5266:4;5221:50;;5069:208;-1:-1:-1;;5069:208:1:o;6017:488::-;-1:-1:-1;;;;;6286:15:1;;;6268:34;;6338:15;;6333:2;6318:18;;6311:43;6385:2;6370:18;;6363:34;;;6433:3;6428:2;6413:18;;6406:31;;;6211:4;;6454:45;;6479:19;;6471:6;6454:45;:::i;:::-;6446:53;6220:285;-1:-1:-1;;;;;;6220:285:1:o;7588:219::-;7737:2;7726:9;7719:21;7700:4;7757:44;7797:2;7786:9;7782:18;7774:6;7757:44;:::i;8224:414::-;8426:2;8408:21;;;8465:2;8445:18;;;8438:30;8504:34;8499:2;8484:18;;8477:62;-1:-1:-1;;;8570:2:1;8555:18;;8548:48;8628:3;8613:19;;8398:240::o;13310:356::-;13512:2;13494:21;;;13531:18;;;13524:30;13590:34;13585:2;13570:18;;13563:62;13657:2;13642:18;;13484:182::o;15183:413::-;15385:2;15367:21;;;15424:2;15404:18;;;15397:30;15463:34;15458:2;15443:18;;15436:62;-1:-1:-1;;;15529:2:1;15514:18;;15507:47;15586:3;15571:19;;15357:239::o;15601:340::-;15803:2;15785:21;;;15842:2;15822:18;;;15815:30;-1:-1:-1;;;15876:2:1;15861:18;;15854:46;15932:2;15917:18;;15775:166::o;16359:342::-;16561:2;16543:21;;;16600:2;16580:18;;;16573:30;-1:-1:-1;;;16634:2:1;16619:18;;16612:48;16692:2;16677:18;;16533:168::o;17294:275::-;17365:2;17359:9;17430:2;17411:13;;-1:-1:-1;;17407:27:1;17395:40;;-1:-1:-1;;;;;17450:34:1;;17486:22;;;17447:62;17444:2;;;17512:18;;:::i;:::-;17548:2;17541:22;17339:230;;-1:-1:-1;17339:230:1:o;17574:186::-;17622:4;-1:-1:-1;;;;;17644:30:1;;17641:2;;;17677:18;;:::i;:::-;-1:-1:-1;17743:2:1;17722:15;-1:-1:-1;;17718:29:1;17749:4;17714:40;;17631:129::o;17765:128::-;17805:3;17836:1;17832:6;17829:1;17826:13;17823:2;;;17842:18;;:::i;:::-;-1:-1:-1;17878:9:1;;17813:80::o;17898:125::-;17938:4;17966:1;17963;17960:8;17957:2;;;17971:18;;:::i;:::-;-1:-1:-1;18008:9:1;;17947:76::o;18028:258::-;18100:1;18110:113;18124:6;18121:1;18118:13;18110:113;;;18200:11;;;18194:18;18181:11;;;18174:39;18146:2;18139:10;18110:113;;;18241:6;18238:1;18235:13;18232:2;;;-1:-1:-1;;18276:1:1;18258:16;;18251:27;18081:205::o;18291:380::-;18370:1;18366:12;;;;18413;;;18434:2;;18488:4;18480:6;18476:17;18466:27;;18434:2;18541;18533:6;18530:14;18510:18;18507:38;18504:2;;;18587:10;18582:3;18578:20;18575:1;18568:31;18622:4;18619:1;18612:15;18650:4;18647:1;18640:15;18504:2;;18346:325;;;:::o;18676:135::-;18715:3;-1:-1:-1;;18736:17:1;;18733:2;;;18756:18;;:::i;:::-;-1:-1:-1;18803:1:1;18792:13;;18723:88::o;18816:127::-;18877:10;18872:3;18868:20;18865:1;18858:31;18908:4;18905:1;18898:15;18932:4;18929:1;18922:15;18948:127;19009:10;19004:3;19000:20;18997:1;18990:31;19040:4;19037:1;19030:15;19064:4;19061:1;19054:15;19080:127;19141:10;19136:3;19132:20;19129:1;19122:31;19172:4;19169:1;19162:15;19196:4;19193:1;19186:15;19212:127;19273:10;19268:3;19264:20;19261:1;19254:31;19304:4;19301:1;19294:15;19328:4;19325:1;19318:15;19344:131;-1:-1:-1;;;;;19419:31:1;;19409:42;;19399:2;;19465:1;19462;19455:12;19480:131;-1:-1:-1;;;;;;19554:32:1;;19544:43;;19534:2;;19601:1;19598;19591:12
Swarm Source
ipfs://90b21747925068e2b95a809dfd2235f6a2462418c2d9737be1b7237b1f8bdc77
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.