// Contract: TheContract
// Target function: function royaltyInfo(
(lastBlinkIndex >= endAt){
            data = abi.encodePacked(data, _svgParts[36 + urlEncodePasses]);
        }     
        
    
        return string(abi.encodePacked(data, _svgParts[36 + urlEncodePasses], generateBlockNumberElements(urlEncodePasses), _svgParts[51 + urlEncodePasses]));
    }
    
    function _circleElement(uint8 urlEncodePasses, bytes memory hexColor, string memory cx, string memory cy) private view returns (bytes memory){
        return abi.encodePacked(_svgParts[24 + urlEncodePasses], hexColor, _svgParts[27 + urlEncodePasses], cx, _svgParts[30 + urlEncodePasses], cy, _svgParts[33 + urlEncodePasses]);
    }
    
    
    
    
    function generateLinearGradient(uint8 urlEncodePasses) internal view returns (string memory){
        
        bytes memory ownerBytes = abi.encodePacked(owner);
        
        bytes memory hexColor1 = abi.encodePacked(uint8(ownerBytes[0]).toHexString(),uint8(ownerBytes[1]).toHexString(),uint8(ownerBytes[2]).toHexString()); 
        bytes memory hexColor2 = abi.encodePacked(uint8(ownerBytes[3]).toHexString(),uint8(ownerBytes[4]).toHexString(),uint8(ownerBytes[5]).toHexString()); 
        bytes memory hexColor3 = abi.encodePacked(uint8(ownerBytes[6]).toHexString(),uint8(ownerBytes[7]).toHexString(),uint8(ownerBytes[8]).toHexString()); 
        
        return string(abi.encodePacked(_svgParts[9+urlEncodePasses], hexColor1, _svgParts[12+urlEncodePasses], hexColor2, _svgParts[15+urlEncodePasses],hexColor3,  _svgParts[18+urlEncodePasses]));
    }
        
    function generateBlockNumberElements(uint8 urlEncodePasses) internal view returns (string memory){
        
        bytes memory blockNumber = bytes(block.number.toString());
         
        uint8 x=93;
        uint8 y=97;
        bytes memory data;
        for(uint i = blockNumber.length; i > 0; i--)
        {
            data =  abi.encodePacked(data, _svgParts[39 + urlEncodePasses],x.toString(),_svgParts[42 + urlEncodePasses],y.toString(),_svgParts[45 + urlEncodePasses],blockNumber[i-1],_svgParts[48 + urlEncodePasses]);
            
            x=x-10;
            
            if(x < 3){
                x=93;
                y=y-10;
            }
       }
        return string(data);
    }
    
    
    function contentType() public pure returns (string memory){
        return "image/svg+xml";
    }
    
    function svg() public view returns (string memory){
        return generateSvg(0);
    }
    function svgDataURI() public view returns (string memory){
        return string(abi.encodePacked("data:", contentType(),",",generateSvg(1)));
    }
    
    
    function getContractBytecode() public view returns (bytes memory o_code) {
        
        address contractAddress =  address(this);
        
        assembly {
            
            // retrieve the size of the code, this needs assembly
            let size := extcodesize(contractAddress)
            // allocate output byte array - this could also be done without assembly
            // by using o_code = new bytes(size)
            o_code := mload(0x40)
            // new "memory end" including padding
            mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f))))
            // store length in memory
            mstore(o_code, size)
            // actually retrieve the code, this needs assembly
            extcodecopy(contractAddress, add(o_code, 0x20), 0, size)
        }
    }
    
    
    // Implementation of supportsInterface as defined in ERC165 standard
    function supportsInterface(bytes4 interfaceId) public view returns (bool) {
        return _supportedInterfaces[interfaceId];
    }
  
    // Total token supply.  
    function totalSupply() public pure returns (uint256) {
        return 1;
    }
    
    // Token by index of all tokens
    function tokenByIndex(uint256 index) public pure returns (uint256) {
        require(index == 0,"Index out of bound");
        return 1;
    }

    // Token by index of owners tokens    
    function tokenOfOwnerByIndex(address owner_, uint256 index) public view returns (uint256) {
        require(index == 0 && owner == owner_,"Index out of bound");
        return 1;
    }
    
    // Token uri to creation metadata
    function tokenURI(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "tokenURI query for nonexistent token");
        return string(abi.encodePacked(
                'data:application/json;charset=utf-8,{%22name%22%3A%22The%20Contract%22%2C%20%22description%22%3A%22The%20Contract%20is%20a%20Non-Fungible%20Token%20contract%20and%20the%20contract%20itself%20is%20the%20creation.%20Token%20holder%20is%20its%20owner.%20The%20contract%20is%20a%20homage%20to%20Fade%20by%20Pak%3A%200x62F5418d9Edbc13b7E07A15e095D7228cD9386c5%22%2C%22created_by%22%3A%22Eivind%20Kleiven%22%2C%22image_data%22%3A%22',generateSvg(1),'%22}'
            ));
    }
    
    // @return number of tokens held by owner_
    function balanceOf(address owner_) public view returns (uint256) {
        require(owner_ != address(0), "Balance query for the zero address");
        return owner_ == owner ? 1 : 0;
    }

    // @return owner of tokenId
    function ownerOf(uint256 tokenId) public view returns (address) {
        require(_exists(tokenId), "Owner query for nonexistent token");
        return owner;
    }

    // Approve to for tokenId. Be aware that an approved address are allowed to transfer tokenId.
    function approve(address to, uint256 tokenId) public {
        require(_exists(tokenId), "Approve query for nonexistent token");
        require(to != owner, "Approval to current owner");
        require(msg.sender == owner || isApprovedForAll(owner, msg.sender),
            "Approve caller is not owner nor approved for all"
        );
        _approve(to, tokenId);
    }

    // @return tokenId approved address.
    function getApproved(uint256 tokenId) public view returns (address) {
        require(_exists(tokenId), "getApproved query for nonexistent token");
        return _tokenApproval;
    }

    // Set approval for all. Be aware that if approval is set to true, then operator may transfer tokenId.
    function setApprovalForAll(address operator, bool approved) public {
        require(owner == msg.sender, "Only owner can set approval for all");
        require(operator != msg.sender, "Approve to caller");

        _operatorApprovals[operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    // @return approval boolean for an owner operator.
    function isApprovedForAll(address owner_, address operator) public view returns (bool) {
        if(owner_ == owner){
            return _operatorApprovals[operator];
        }
        
        return false;
    }


    function transferFrom(address from, address to, uint256 tokenId) public {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(msg.sender, tokenId), "Transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId) public {
        safeTransferFrom(from, to, tokenId, "");
    }

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
        require(_isApprovedOrOwner(msg.sender, tokenId), "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 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(_exists(tokenId), "Transfer of nonexistent token");
        require(owner == from, "Transfer of token that is not own");
        require(to != address(0), "Transfer to the zero address. Burn instead.");

        _approve(address(0), tokenId);
        _removeOffer();

        owner = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @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 returns (bool) {
        return (tokenId == 1 && owner != address(0));
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
        require(_exists(tokenId), "Operator query for nonexistent token");
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function burn(uint256 tokenId) public {
        require(_exists(tokenId),"Try to burn nonexistent token.");

        // Clear approvals
        _approve(address(0), tokenId);
 
        owner = address(0);
        
        _removeOffer();
        
        if(bid > 0){
            uint amount = bid;
            payable(bidder).transfer(amount);
            _resetBid();
        }
        
        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApproval = to;
        emit Approval(owner, 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)
    {
        
        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(to) }
        
        if (size > 0) {
            
            try IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver(to).onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("Transfer to non ERC721Receiver implementer");
                } else {
                    // solhint-disable-next-line no-inline-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }
    
    
    function destruct() public {
        require(msg.sender == owner, "Only owner can destruct contract.");
      
        if(bid > 0){
            payable(bidder).transfer(bid);
            _resetBid();
        }
        
        selfdestruct(payable(msg.sender));
    }
    
    
    
     // ENTER MARKETPLACE

    event Offered(uint indexed price, address indexed offeredTo);
    event RecievedBid(uint indexed value, address indexed bidder);
    event WithdrawnBid(uint indexed value, address indexed bidder);
    event Sold(uint indexed price, address indexed seller, address indexed buyer);
    event OfferRemoved();


    bool public hasBid;
    uint public bid;
    address public bidder;

    
    uint public offer;
    bool public isForSale;
    address public onlySellTo;
    address public seller;

    function _removeOffer() internal {
        isForSale = false;
        offer = 0;
        seller = address(0);
        onlySellTo = address(0);
    }
    
    function _resetBid() internal {
        hasBid=false;
        bid=0;
        bidder=address(0);
    }

    function removeOffer() public {
        require(owner == msg.sender, "Only owner can remove offer.");
        _removeOffer();
        emit OfferRemoved();
    }

    function offerForSale(uint priceInWei) public {
        require(owner == msg.sender, "Only owner can offer for sale.");
        offerForSaleToAddress(priceInWei, address(0));
    }
    
    function offerForSaleToAddress(uint priceInWei, address toAddress) public {
        require(owner == msg.sender, "Only owner can offer for sale.");
        require(priceInWei > 0, "Cannot offer for free.");
        
        offer = priceInWei;
        seller = msg.sender;
        onlySellTo = toAddress;
        isForSale = true;
        emit Offered(priceInWei, toAddress);
    }


    function buy() payable public {
        require(isForSale, "The Contract is not offered to buy.");
        require(onlySellTo == address(0) || onlySellTo == msg.sender,"Not offered to this buyer.");
        require(msg.value >= offer, "Sent less than offer.");
        require(seller == owner, "Only owner allowed to sell.");
    
        address payable beneficiary = payable(seller);
 

        _safeTransfer(seller, msg.sender, 1, "");

        uint amountToArtist = msg.value/10;
        if(amountToArtist > 0){
            _artistAccount.transfer(amountToArtist);
        }
        
        if(amountToArtist < msg.value)
        {

            beneficiary.transfer(msg.value - amountToArtist);
        }
        
        emit Sold(msg.value, seller, msg.sender);
        
    }
    
    
     function enterBid() public payable {
        require(_exists(1), "Nothing exist to bid on");
        require(owner != msg.sender, "Owner cannot bid");
        require(msg.value > bid, "Not allowed to bid less than current bid");

        address payable currentBidder = payable(bidder);
        uint currentBid = bid;
        
        hasBid = true;
        bidder = msg.sender;
        bid = msg.value;
        
        if (currentBid > 0) {
            // Refund previous bid
            currentBidder.transfer(currentBid);
        }
        
        emit RecievedBid(msg.value, msg.sender);
    }
    
    
    function acceptBid(uint minPrice) public {
        require(owner == msg.sender, "Only owner can accept bid.");
        require(bid >= minPrice, "Bid lower than given minimum price");

        uint amount = bid;
        address payable beneficiary = payable(owner);
            
        _safeTransfer(msg.sender, bidder, 1, "");

    
        emit Sold(amount, msg.sender, bidder);
        
        _resetBid();
        
        
        uint amountToArtist = amount/10;
        if(amountToArtist > 0){
            _artistAccount.transfer(amountToArtist);
        }
        
        if(amountToArtist < amount)
        {

            beneficiary.transfer(amount - amountToArtist);
        }

    
        
    }


  function withdrawBid() public {
        require(bidder == msg.sender, "Only bidder can withdraw bid");
        
        uint amount = bid;
        address payable beneficiary = payable(bidder);
        
        emit WithdrawnBid(bid, msg.sender);
        
        _resetBid();

        beneficiary.transfer(amount);
    }


    /// LEAVE MARKETPLACE
    
    
    
    /// BEGIN NFT Royalty Standard (ERC-2981)