// Contract: Etherwriter
// Target function: function changeWebURI(string memory _newWebsite) onlyAdmin public
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) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC, U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}';

	event ChangedText(address indexed Owner, uint256 indexed tokenId, string firstLine, string secondLine, string thirdLine, string fourthLine);

	modifier onlyAdmin {
		require(_msgSender() == _smartContractOwner, _strNotAuthorized);
		_;
	}

	modifier onlyOwner(uint256 tokenId) {
		require(_msgSender() == ownerOf(tokenId), _strNotAuthorized);
		_;
	}

	constructor() ERC721() {
		_smartContractOwner = msg.sender;
	}

	// Aux internal functions

	function _createTextBlock(uint256 tokenId, uint256 level) private view returns(string memory) {
		string memory text = tokenData[tokenId].texta;
		if(level == 1) {
			text = tokenData[tokenId].textb;
		}
		if(level == 2) {
			text = tokenData[tokenId].textc;
		}
		else if(level == 3) {
			text = tokenData[tokenId].textd;
		}

		return string(
			abi.encodePacked(
				'<text visibility="hidden" x="100" y="', Strings.toString(level), '90" font-family="Xe" font-size="40" fill="', tokenData[tokenId].color, '">',
				text
			)
		);
	}

	function _determineColor(uint256 _tokenId) private pure returns(string memory) {
		string memory _color = '#888888';
		if(_tokenId == 0) {
			// 1, token 0, electric pink, 0.01%, non-transferrable.
			_color = '#F9016A';
		}
		else if(_tokenId > 0 && _tokenId < 11) {
			// 10, 1 to 10, phosphor cerulean, 0.1%.
			_color = '#01B3F9';
		}
		else if(_tokenId > 10 && _tokenId < 111) {
			//100, 11 to 110, phosphor red, 1%.
			_color = '#FF1900';
		}
		else if(_tokenId > 110 && _tokenId < 1111) {
			//1000, 111 to 1110, phosphor green, 10%.
			_color = '#19FF00';
		}
		// 8889, 1111 to 9999, light gray, 88.89%.

		return _color;
	}

	function modifyTokenData(uint256 tokenId, string memory a, string memory b, string memory c, string memory d) private {
		require(Strings.stringLength(a) < 41, _strTextTooLong);
		require(Strings.stringLength(b) < 41, _strTextTooLong);
		require(Strings.stringLength(c) < 41, _strTextTooLong);
		require(Strings.stringLength(d) < 41, _strTextTooLong);

		tokenData[tokenId].texta = a;
		tokenData[tokenId].textb = b;
		tokenData[tokenId].textc = c;
		tokenData[tokenId].textd = d;
	}

	// Main public functions

	/// @dev Use this function to change the token's text.
	///	 Note: Only token's owner can change this.
	/// @param tokenId token ID.
	/// @param firstLine First line of text. Must be 40 characters or less.
	/// @param secondLine Second line of text. Must be 40 characters or less.
	/// @param thirdLine Third line of text. Must be 40 characters or less.
	/// @param fourthLine Fourth line of text. Must be 40 characters or less.
	function changeTokenText(uint256 tokenId, string memory firstLine, string memory secondLine, string memory thirdLine, string memory fourthLine) onlyOwner(tokenId) public {
		require(tokenId < _mintedTokens, _strOutOfBounds);
		modifyTokenData(tokenId, firstLine, secondLine, thirdLine, fourthLine);
		emit ChangedText(_msgSender(), tokenId, firstLine, secondLine, thirdLine, fourthLine);
	}