

var workspace; 
var checkboxChecked = 0;
var editor;
const term = new Terminal({
	cursorBlink: true,
	macOptionIsMeta: true,
	scrollback: true,
});
var userREPLInstalled = false;
const fit = new FitAddon.FitAddon();
var replCharacteristicObj = null;

term.loadAddon(fit);
term.loadAddon(new WebLinksAddon.WebLinksAddon());
term.loadAddon(new SearchAddon.SearchAddon());

term.open(document.getElementById("terminal"));
fit.fit();


function Initialization(){
	document.getElementById("dropdownVue").childNodes.forEach(element => {
		if(element.id != undefined){
			let checkboxContainer = element;
			checkboxContainer.childNodes.forEach(element2 => {
				if(element2.type == "checkbox"){
					if(element2.checked){
						checkboxChecked++;
					}
				}
			});
			
		}
	});editor = CodeMirror.fromTextArea(document.getElementById("code"), {
		mode: { name: "python", version: 3, singleLineStringErrors: false },
		lineNumbers: true,
		indentUnit: 4,
		matchBrackets: true,
		readOnly: false // Ajoutez cette ligne pour rendre l'éditeur en lecture seule
	});
	
	
		
	
	
		
	editor.setOption("theme", "ayu-dark");
	InitBlockly();
	ResizeView();
	InitGrosChiffre();
	initChartConf();
	Blockly.svgResize(workspace);
	
}
function InitBlockly(){
	workspace = Blockly.inject('blocklyDiv',{toolbox: document.getElementById('toolbox'),
				theme: 'dark',
				zoom:
					{controls: true,
					wheel: true,
					startScale: 1.0,
					maxScale: 3,
					minScale: 0.3,
					scaleSpeed: 1.2,
					pinch: true},
				trashcan: true
	});
	Blockly.svgResize(workspace);
}
Initialization();




const logoScthic = "data:image/svg+xml;base64, "
const logoGomme = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+CiAgICA8cGF0aCBzdHlsZT0idGV4dC1pbmRlbnQ6MDt0ZXh0LWFsaWduOnN0YXJ0O2xpbmUtaGVpZ2h0Om5vcm1hbDt0ZXh0LXRyYW5zZm9ybTpub25lO2Jsb2NrLXByb2dyZXNzaW9uOnRiOy1pbmtzY2FwZS1mb250LXNwZWNpZmljYXRpb246Qml0c3RyZWFtIFZlcmEgU2FucyIgZD0iTSAxOC45MDYyNSA0LjA5Mzc1IEMgMTguMTAwNTUxIDQuMDkyNDcwNiAxNy4yNjc0MzYgNC4zNjY0NDU0IDE2LjYyNSA0LjkzNzUgTCAxNi42MjUgNC45Njg3NSBMIDE2LjU5Mzc1IDUgTCA0LjkwNjI1IDE2LjU5Mzc1IEMgMy42OTM3NzEgMTcuODA2MjI5IDMuNzAxNjQwOCAxOS43Nzc2MjcgNC44NDM3NSAyMS4wNjI1IEwgNC44NzUgMjEuMDkzNzUgTCA0LjkwNjI1IDIxLjA5Mzc1IEwgMTAuOTA2MjUgMjcuMDkzNzUgQyAxMi4xMTg3MjkgMjguMzA2MjI5IDE0LjA5MDEyNyAyOC4yOTgzNTkgMTUuMzc1IDI3LjE1NjI1IEwgMTUuMzc1IDI3LjEyNSBMIDE1LjQwNjI1IDI3LjA5Mzc1IEwgMjcgMTUuNSBDIDI4LjI2NjY0OCAxNC4yMzMzNTIgMjguMzA2MjI5IDEyLjIxMjQ3OSAyNy4wOTM3NSAxMSBMIDIxLjA5Mzc1IDUgQyAyMC40ODc1MTEgNC4zOTM3NjA1IDE5LjcxMTk0OSA0LjA5NTAyOTQgMTguOTA2MjUgNC4wOTM3NSB6IE0gMTguODc1IDYuMTI1IEMgMTkuMTk0MzAxIDYuMTIzNzIgMTkuNDkzNzM5IDYuMjEyNDkgMTkuNjg3NSA2LjQwNjI1IEwgMjUuNjg3NSAxMi40MDYyNSBDIDI2LjA3NTAyMSAxMi43OTM3NzEgMjYuMTI3MTAyIDEzLjU2MDM5OCAyNS41OTM3NSAxNC4wOTM3NSBMIDIwLjU2MjUgMTkuMTI1IEwgMTIuOTA2MjUgMTEuNDY4NzUgTCAxNy45Njg3NSA2LjQzNzUgTCAxOCA2LjQwNjI1IEMgMTguMjUyOTA3IDYuMTk2NDU5MSAxOC41Njg5MzIgNi4xMjYyMjY0IDE4Ljg3NSA2LjEyNSB6IE0gMTEuNDY4NzUgMTIuOTA2MjUgTCAxOS4xMjUgMjAuNTYyNSBMIDE0LjAzMTI1IDI1LjY1NjI1IEMgMTQuMDIwNTQgMjUuNjY1NzUgMTQuMDEwOTcgMjUuNjc4NCAxNCAyNS42ODc1IEMgMTMuNDgzMjQ3IDI2LjExNjA1OSAxMi42OTE5NjQgMjYuMDY2OTY0IDEyLjMxMjUgMjUuNjg3NSBMIDYuMzQzNzUgMTkuNzUgQyA2LjMyNzgyOTIgMTkuNzMyMDg5IDYuMzI3MjQ2NCAxOS43MDYxMzEgNi4zMTI1IDE5LjY4NzUgQyA1LjkwMzEzMDMgMTkuMTcwMyA1LjkzODQ1MyAxOC4zNzQwNDcgNi4zMTI1IDE4IEwgMTEuNDY4NzUgMTIuOTA2MjUgeiIgY29sb3I9IiMwMDAiIG92ZXJmbG93PSJ2aXNpYmxlIiBmb250LWZhbWlseT0iQml0c3RyZWFtIFZlcmEgU2FucyIvPgo8L3N2Zz4=";
const logoimg = "data:image/svg+xml;base64, ";
const crossimg = "data:image/svg+xml;base64, ";
const csvimg = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gU3ZnIFZlY3RvciBJY29ucyA6IGh0dHA6Ly93d3cub25saW5ld2ViZm9udHMuY29tL2ljb24gLS0+DQo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTAwMCAxMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAwIDEwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPG1ldGFkYXRhPiBTdmcgVmVjdG9yIEljb25zIDogaHR0cDovL3d3dy5vbmxpbmV3ZWJmb250cy5jb20vaWNvbiA8L21ldGFkYXRhPg0KPGc+PHBhdGggZD0iTTk4NC43LDY3MC4yTDc4Mi43LDUyNi40Yy00LjMtMy05LjctMy40LTE0LjQtMWMtNC42LDIuNC03LjUsNy42LTcuNSwxMi44bDAuMSw2OC4xSDU3OS4yYy03LjcsMC0xNS4yLDUuNC0xNS4yLDEzLjJ2MTI1LjJjMCw3LjcsNy41LDEzLjEsMTUuMiwxMy4xaDE4My42djY4LjZjMCw1LjIsMiwxMCw2LjcsMTIuNGM0LjcsMi40LDkuMywyLDEzLjYtMS4xTDk4NC44LDY5M2MzLjctMi42LDUuMi02LjksNS4yLTExLjRjMCwwLDAsMCwwLDBDOTkwLDY3Ny4xLDk4OC40LDY3Mi45LDk4NC43LDY3MC4yeiIvPjxwYXRoIGQ9Ik02NTMuOSw4MTIuNWgtNzFsMCwwYy0xMC41LDAtMTguOSw4LjUtMTguOSwxOC45aC0wLjF2MzIuOUgxMTlWMzQ4LjVoMTk0YzEwLjUsMCwxOC45LTguNSwxOC45LTE4Ljl2LTE5NGgyMzEuOXYzOThoMC4xYzAuMiwxMC4zLDguNiwxOC41LDE4LjksMTguNWg3MWMxMC4zLDAsMTguNy04LjMsMTguOS0xOC41aDB2LTAuNHYwYzAsMCwwLDAsMCwwVjg5LjVoLTAuMXYtNDRjMC0xMC41LTguNS0xOC45LTE4LjktMTguOUg2MjdsMCwwSDMxM2wwLDBIMjk0bC0yODQsMjg0djI2Ljh2MTEuMXY1NzkuMnYyNi44YzAsMTAuNSw4LjUsMTguOSwxOC45LDE4LjloMTcuM2g1OTAuM2gxNy4zYzEwLjUsMCwxOC45LTguNSwxOC45LTE4Ljl2LTI2LjhoMC4xdi05Ni4ydjBDNjcyLjgsODIxLDY2NC40LDgxMi41LDY1My45LDgxMi41eiIvPjxwYXRoIGQ9Ik0yMzkuMyw2NTUuMWM5LjEsMCwxNyw2LjgsMTkuNiwxNC43bDI2LjQtMTIuM2MtNi4xLTEzLjktMTkuNC0yOS40LTQ1LjktMjkuNGMtMzEuNywwLTU1LjYsMjEuMS01NS42LDUyLjNjMCwzMS4xLDIzLjksNTIuMyw1NS42LDUyLjNjMjYuNSwwLDQwLTE2LjEsNDUuOS0yOS41TDI1OC44LDY5MWMtMi42LDcuOS0xMC41LDE0LjctMTkuNiwxNC43Yy0xNC43LDAtMjQuNS0xMS4yLTI0LjUtMjUuM0MyMTQuNyw2NjYuMywyMjQuNiw2NTUuMSwyMzkuMyw2NTUuMXoiLz48cGF0aCBkPSJNMzQzLDcwN2MtMTMuNiwwLTI1LTUuOC0zMi42LTEzbC0xNS45LDIyLjdjMTAuNyw5LjcsMjUuNCwxNi4xLDQ3LDE2LjFjMjcuMSwwLDQzLjYtMTIuOSw0My42LTM1LjFjMC0zNy42LTU2LjItMjkuNC01Ni4yLTM4LjljMC0yLjYsMS43LTQuNSw3LjctNC41YzkuNSwwLDIwLjksMy4zLDI5LjcsMTBsMTYuNC0yMS43Yy0xMS41LTkuNC0yNi40LTE0LjEtNDIuOS0xNC4xYy0yNy43LDAtNDIsMTYuNC00MiwzMy41YzAsMzkuOCw1Ni40LDMwLDU2LjQsMzkuN0MzNTQuMiw3MDUuNCwzNDguNyw3MDcsMzQzLDcwN3oiLz48cGF0aCBkPSJNNDI2LjMsNjI5LjhoLTM0LjdsMzcuMywxMDFoMzguNWwzNy4zLTEwMUg0NzBsLTIxLjgsNjhMNDI2LjMsNjI5Ljh6Ii8+PC9nPg0KPC9zdmc+"
const imgPowerSymbBlack = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE4LjEuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMzAuMTQzIDMwLjE0MyIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzAuMTQzIDMwLjE0MzsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPGc+DQoJPHBhdGggc3R5bGU9ImZpbGw6IzAzMDEwNDsiIGQ9Ik0yMC4wMzQsMi4zNTd2My44MjRjMy40ODIsMS43OTgsNS44NjksNS40MjcsNS44NjksOS42MTljMCw1Ljk4LTQuODQ4LDEwLjgzLTEwLjgyOCwxMC44Mw0KCQljLTUuOTgyLDAtMTAuODMyLTQuODUtMTAuODMyLTEwLjgzYzAtMy44NDQsMi4wMTItNy4yMTUsNS4wMjktOS4xMzZWMi42ODlDNC4yNDUsNC45MTgsMC43MzEsOS45NDUsMC43MzEsMTUuODAxDQoJCWMwLDcuOTIxLDYuNDIsMTQuMzQyLDE0LjM0LDE0LjM0MmM3LjkyNCwwLDE0LjM0Mi02LjQyMSwxNC4zNDItMTQuMzQyQzI5LjQxMiw5LjYyNCwyNS41MDEsNC4zNzksMjAuMDM0LDIuMzU3eiIvPg0KCTxwYXRoIHN0eWxlPSJmaWxsOiMwMzAxMDQ7IiBkPSJNMTQuNzk1LDE3LjY1MmMxLjU3NiwwLDEuNzM2LTAuOTMxLDEuNzM2LTIuMDc2VjIuMDhjMC0xLjE0OC0wLjE2LTIuMDgtMS43MzYtMi4wOA0KCQljLTEuNTcsMC0xLjczMiwwLjkzMi0xLjczMiwyLjA4djEzLjQ5NkMxMy4wNjIsMTYuNzIyLDEzLjIyNSwxNy42NTIsMTQuNzk1LDE3LjY1MnoiLz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjwvc3ZnPg0K"


// document.getElementById('coBtn').src = imgPowerSymbBlack;
document.getElementById('coBtn').src = "ressource/svg/001-usb.svg";
document.getElementById('pointToDelete').src = "ressource/svg/005-la-gomme.svg";
// document.getElementById('deleteLastdata').src = logoGomme;
document.getElementById('logo').src = logoimg;
document.getElementById('exportcsv').src = csvimg;
document.getElementById('sclogo').src = logoScthic;
document.getElementById('setLine').src = "ressource/svg/007-graphique-a-nuage-de-points.svg";

var stateconnected = false;

function changeView(){
	document.getElementById('dropdownVue').childNodes.forEach(element => {
		if(element.id != undefined){
			let checkboxContainer = element;
			checkboxContainer.childNodes.forEach(element2 => {
				if(element2.type == "checkbox"){
					
					if(element2.checked){
						document.getElementById(element2.name).style.display = "block";
						// console.log(element2.name)
					}else{
						if(element2.name != "Blockly"){
							InitBlockly();
							Blockly.svgResize(workspace);
							
						}
						document.getElementById(element2.name).style.display = "none";
					}	
				}
			});
			
		}
	});
}


function ImportLibAfficheur(){
	var cmd ="";
	cmd += "import os" + "\r\n"
	cmd += "try:" + "\r\n"
	cmd += "    f = open('lib/afficheurWEBAPP.py', 'x')" + "\r\n"
	cmd += "    f.close()" + "\r\n"
	cmd += "    f = open('lib/afficheurWEBAPP.py', 'w')" + "\r\n"
	cmd += "    f.write('\\n'+ \"import json\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"from ppy import millis\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"from sys import stdout\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"class afficheursWEBAPP(object):\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"  def __init__(self):\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"    self.REFRESH_RATE_MS = 50\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"    self.previousMessageTimestampMsGrosChiffre = 0\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"    self.identifierCounter = 0\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"    self.identifierList = {}\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"  def envoyer(self,valeur,inputValue=None,unit=None,identifier=None,inputUnit=None,refreshAnyway=False):\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"    now = millis()\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"    if ( now - self.previousMessageTimestampMsGrosChiffre ) >= self.REFRESH_RATE_MS :\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"      self.previousMessageTimestampMsGrosChiffre = now\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"      querySrc = json.dumps([\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"        str(identifier),\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"        str(valeur),\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"        str(unit),\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"        str(inputValue),\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"        str(inputUnit)\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"      ])\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"      querySerialized = json.dumps(querySrc)\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"      querySerialized = str(len(querySerialized)) + querySerialized\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"      print(\'\\\\n\')\")" + "\r\n"
	cmd += "    f.write('\\n'+ \"      stdout.write(querySerialized)\")" + "\r\n"
	cmd += "    f.close()" + "\r\n"
	cmd += "except:  print(\"lib already exist\")" + "\r\n"
	if ( !ppy.isInRAWReplMode() )
		ppy.enterRawRepl().then( _ =>{		
			return ppy.exec(cmd);	
		});	
	else
		 return ppy.exec(cmd);	
}

function ImportLibTone(){
	var code ="";
	code += "import os" + "\r\n"
	code += "try:" + "\r\n";
	code += "	f = open('lib/tone.py', 'x')" + "\r\n";
	code += " 	f.close()" + "\r\n";
	code += " 	f = open('lib/tone.py', 'w')" + "\r\n";
	code += "	f.write('\\nfrom ppy import Timer,Pin,delay')" + "\r\n";
	code += "	f.write('\\n_toneAvailablePin = {')" + "\r\n";
	code += "	f.write('\\n\"A1\":[2,1],\"D0\":[3,2],\"D1\":[3,1],\"D3\":[2,1],\"D4\":[3,2],\"D6\":[2,2],\"D8\":[3,4],\"D10\":[1,3],\"D11\":[1,2],\"D13\":[1,1],}\\n')" + "\r\n";
	code += "	f.write(\"\\nNOTES = {\\n'B1': 62,\\n'B0': 31,\\n'GS4': 415,\\n'B4': 494, \\n'GS5': 831, \\n'B5': 988, \\n'GS6': 1661, \\n'B6': 1976, \\n'C7': 2093, \\n'D7': 2349, \\n'E7': 2637, \\n'F7': 2794, \\n'GS7': 3322, \\n'AS7': 3729, \\n'A4': 440, \\n'A5': 880, \\n'A6': 1760, \\n'A7': 3520, \\n'B7': 3951, \\n'A1': 55, \\n'A2': 110, \\n'A3': 220, \\n'C8': 4186, \\n'D8': 4699, \\n'CS5': 554, \\n'CS4': 277, \\n'CS7': 2217, \\n'CS6': 1109, \\n'CS1': 35, \\n'DS8': 4978, \\n'CS3': 139, \\n'CS2': 69, \\n'REST': 0, \\n'FS1': 46, \\n'FS2': 93, \\n'FS3': 185, \\n'FS4': 370, \\n'FS5': 740, \\n'FS6': 1480, \\n'FS7': 2960, \\n'G2': 98, \\n'G3': 196, \\n'CS8': 4435, \\n'G1': 49, \\n'G6': 1568, \\n'G7': 3136, \\n'F3': 175, \\n'F2': 87, \\n'F1': 44, \\n'DS2': 78, \\n'DS3': 156, \\n'DS1': 39, \\n'G4': 392, \\n'F4': 349, \\n'DS4': 311, \\n'AS4': 466, \\n'AS3': 233, \\n'AS2': 117, \\n'AS1': 58, \\n'DS5': 622, \\n'F5': 698, \\n'G5': 784, \\n'AS5': 932, \\n'DS6': 1245, \\n'F6': 1397, \\n'AS6': 1865, \\n'DS7': 2489, \\n'E1': 41, \\n'E2': 82, \\n'E3': 165, \\n'E4': 330, \\n'E5': 659, \\n'D1': 37, \\n'E6': 1319, \\n'D3': 147, \\n'D2': 73, \\n'D5': 587, \\n'D4': 294, \\n'C6': 1047, \\n'D6': 1175, \\n'C4': 262, \\n'C5': 523, \\n'GS1': 52, \\n'C2': 65, \\n'C3': 131, \\n'C1': 33, \\n'GS2': 104, \\n'GS3': 208, \\n'B3': 247, \\n'B2': 123}\")" + "\r\n";	
	code += "	f.write('\\ndef tone(pin,frequency,durationMs=None,intensity=None):')" + "\r\n";
	code += "	f.write('\\n  if pin not in _toneAvailablePin :')" + "\r\n";
	code += "	f.write('\\n    raise ValueError(\"pin param. (provided : \"+str(pin)+\") must be one of : A1/D0/D1/D3/D4/D6/D8/D10/D11/D13.\")')" + "\r\n";
	code += "	f.write('\\n  if not(isinstance(intensity,int)) : intensity = 10')" + "\r\n";
	code += "	f.write('\\n  elif intensity > 50 : intensity = 50')" + "\r\n";
	code += "	f.write('\\n  if frequency == 0 :')" + "\r\n";
	code += "	f.write('\\n    Timer(_toneAvailablePin[pin][0])')" + "\r\n";
	code += "	f.write('\\n    return')" + "\r\n";
	code += "	f.write('\\n  timInstance = Timer(_toneAvailablePin[pin][0],freq=frequency)')" + "\r\n";
	code += "	f.write('\\n  timInstance.channel(_toneAvailablePin[pin][1],Timer.PWM,pin=Pin(pin),pulse_width_percent=intensity)')" + "\r\n";
	code += "	f.write('\\n  if isinstance(durationMs,int) :')" + "\r\n";
	code += "	f.write('\\n    delay(durationMs)')" + "\r\n";
	code += "	f.write('\\n    timInstance.deinit()')" + "\r\n";
	code += "	f.close()" + "\r\n";
	code += "except:  print(\"lib already exist\")" + "\r\n";
	if ( !ppy.isInRAWReplMode() )
		ppy.enterRawRepl().then( _ =>{		
			return ppy.exec(code);	
		});	
	else
		 return ppy.exec(code);	
}
function ImportLibI2C(){
	var code ="";
	code += "try:" + "\r\n";
	code += "	f = open('lib/I2CRelayController.py', 'x')" + "\r\n";
	code += "	f.close()" + "\r\n";
	code += "	f = open('lib/I2CRelayController.py', 'w')" + "\r\n";
	code += "	f.write('\\n# Begin I2C Relay Controller Driver')" + "\r\n";
	code += "	f.write('\\n# Work with :')" + "\r\n";
	code += "	f.write('\\n# - Sciencethic 651 071 4-Channel Relay Controller')" + "\r\n";
	code += "	f.write('\\n# - Grove 4-Channel SPDT Relay (103020133)')" + "\r\n";
	code += "	f.write('\\nfrom ppy import I2C')" + "\r\n";
	code += "	f.write('\\nfrom ppy import delay')" + "\r\n";
	code += "	f.write('\\nclass RelayController(object):')" + "\r\n";
	code += "	f.write('\\n	i2cBus = I2C()')" + "\r\n";
	code += "	f.write('\\n	')" + "\r\n";
	code += "	f.write('\\n	DEFAULT_IIC_ADDR = 0x11')" + "\r\n";
	code += "	f.write('\\n	CMD_READ_FIRMWARE_VER = 0x13')" + "\r\n";
	code += "	f.write('\\n	CMD_CHANNEL_CTRL = 0x10')" + "\r\n";
	code += "	f.write('\\n	CMD_SAVE_I2C_ADDR = 0x11')" + "\r\n";
	code += "	f.write('\\n	FW_VER = 0x01')" + "\r\n";
	code += "	f.write('\\n	def __init__(self,addr=DEFAULT_IIC_ADDR):')" + "\r\n";
	code += "	f.write('\\n	')" + "\r\n";
	code += "	f.write('\\n		if self.i2cBus.is_ready(addr) is not True :')" + "\r\n";
	code += "	f.write('\\n			raise Exception(\"\\\\n\\\\nI2C : device not responding.\\\\nTry RelayController.FIND() to detect the user-definied IIC address.\\\\nSpecify an user-definied address by adding addr=<<your device address>> param to RelayController object constructor.\\\\n\")')" + "\r\n";
	code += "	f.write('\\n	')" + "\r\n";
	code += "	f.write('\\n		self._i2cAddr = addr')" + "\r\n";
	code += "	f.write('\\n		self.channel_state = 0x00')" + "\r\n";
	code += "	f.write('\\n		')" + "\r\n";
	code += "	f.write('\\n	def changeI2CAddress(self,new_addr):')" + "\r\n";
	code += "	f.write('\\n		self.i2cBus.send(bytearray([self.CMD_SAVE_I2C_ADDR,new_addr]),addr=self._i2cAddr)')" + "\r\n";
	code += "	f.write('\\n		self._i2cAddr = new_addr')" + "\r\n";
	code += "	f.write('\\n		delay(20)')" + "\r\n";
	code += "	f.write('\\n		')" + "\r\n";
	code += "	f.write('\\n	def getChannelState(self):')" + "\r\n";
	code += "	f.write('\\n		return self.channel_state')" + "\r\n";
	code += "	f.write('\\n		')" + "\r\n";
	code += "	f.write('\\n	def getFirmwareVersion(self):')" + "\r\n";
	code += "	f.write('\\n		self.i2cBus.send(self.CMD_READ_FIRMWARE_VER,addr=self._i2cAddr)')" + "\r\n";
	code += "	f.write('\\n		addr = self.i2cBus.recv(1,addr=self._i2cAddr);')" + "\r\n";
	code += "	f.write('\\n		delay(20)')" + "\r\n";
	code += "	f.write('\\n		return addr')" + "\r\n";
	code += "	f.write('\\n		')" + "\r\n";
	code += "	f.write('\\n	def channelCtrl(self,state):')" + "\r\n";
	code += "	f.write('\\n		self.channel_state = state;')" + "\r\n";
	code += "	f.write('\\n		self.i2cBus.send(bytearray([self.CMD_CHANNEL_CTRL,self.channel_state]),addr=self._i2cAddr)')" + "\r\n";
	code += "	f.write('\\n		delay(20)')" + "\r\n";
	code += "	f.write('\\n		')" + "\r\n";
	code += "	f.write('\\n	def turn_on_channel(self,channel):')" + "\r\n";
	code += "	f.write('\\n		if channel < 1 or channel > 8 :')" + "\r\n";
	code += "	f.write('\\n			raise Exception(\\'Invalid channel number. Valid 1,2,3,4(5,6,7,8)\\')')" + "\r\n";
	code += "	f.write('\\n		self.channel_state |= (1 << (channel - 1))')" + "\r\n";
	code += "	f.write('\\n		self.channelCtrl(self.channel_state)')" + "\r\n";
	code += "	f.write('\\n		delay(20)')" + "\r\n";
	code += "	f.write('\\n		')" + "\r\n";
	code += "	f.write('\\n	def turn_off_channel(self,channel):')" + "\r\n";
	code += "	f.write('\\n		if channel < 1 or channel > 8 :')" + "\r\n";
	code += "	f.write('\\n			raise Exception(\\'Invalid channel number. Valid 1,2,3,4(5,6,7,8)\\')')" + "\r\n";
	code += "	f.write('\\n		self.channel_state &= ~(1 << (channel - 1))')" + "\r\n";
	code += "	f.write('\\n		self.channelCtrl(self.channel_state)')" + "\r\n";
	code += "	f.write('\\n		delay(20)')" + "\r\n";
	code += "	f.write('\\n		')" + "\r\n";
	code += "	f.write('\\n	# Static method. Try to find the relay controller address on the IIC bus.')" + "\r\n";
	code += "	f.write('\\n	# Might be useful as the device IIC address can be change by the end user.')" + "\r\n";
	code += "	f.write('\\n	# Return -1 if not found.')" + "\r\n";
	code += "	f.write('\\n	def FIND():')" + "\r\n";
	code += "	f.write('\\n		res = RelayController.i2cBus.scan()')" + "\r\n";
	code += "	f.write('\\n		found = False')" + "\r\n";
	code += "	f.write('\\n		if len(res) is 0 :')" + "\r\n";
	code += "	f.write('\\n			print(\"No IIC device found.\")')" + "\r\n";
	code += "	f.write('\\n		else :')" + "\r\n";
	code += "	f.write('\\n			for addr in res :')" + "\r\n";
	code += "	f.write('\\n				RelayController.i2cBus.send(RelayController.CMD_READ_FIRMWARE_VER,addr=addr)')" + "\r\n";
	code += "	f.write('\\n				fwVer = RelayController.i2cBus.recv(1,addr=addr)')" + "\r\n";
	code += "	f.write('\\n				delay(20)')" + "\r\n";
	code += "	f.write('\\n				if int.from_bytes(fwVer,\\'big\\') is RelayController.FW_VER :')" + "\r\n";
	code += "	f.write('\\n					strHexAddr = \"0x\".join(\"{:02x}\".format(c) for c in res)')" + "\r\n";
	code += "	f.write('\\n					print(\"\\\\nRelay controller found. Address is : 0x\"+strHexAddr+\".\\\\nAdd param address in RelayController constructor to override the default address :\\\\n-> RelayController(addr=0x\"+strHexAddr+\")\\\\n\")')" + "\r\n";
	code += "	f.write('\\n					found = True')" + "\r\n";
	code += "	f.write('\\n			if found is False :')" + "\r\n";
	code += "	f.write('\\n				print(len(res),\"IIC device found. Relay controller not detected...\")')" + "\r\n";
	code += "	f.write('\\n				')" + "\r\n";
	code += "	f.write('\\n# End I2C Relay Controller Driver')" + "\r\n";
	code += "	f.close()" + "\r\n";
	code += "except:	print('lib already exist')" + "\r\n";
	if ( !ppy.isInRAWReplMode() )
		ppy.enterRawRepl().then( _ =>{		
			return ppy.exec(code);	
		});	
	else
		 return ppy.exec(code);	
}
function ImportLibLCD(){
	var code ="";
	code += "try:" + "\r\n";
	code += "	f = open('lib/LCD16x2RGB.py', 'x')" + "\r\n";
	code += "	f.close()" + "\r\n";
	code += "	f = open('lib/LCD16x2RGB.py', 'w')" + "\r\n";
	code += "	f.write('\\n# Begin I2C LCD 16x2 RGB Driver')" + "\r\n";
	code += "	f.write('\\n# Work with :')" + "\r\n";
	code += "	f.write('\\n# Grove - LCD RGB Backlight')" + "\r\n";
	code += "	f.write('\\n# AKA Sciencethic 651 018')" + "\r\n";
	code += "	f.write('\\nfrom ppy import I2C')" + "\r\n";
	code += "	f.write('\\nfrom ppy import delay,udelay')" + "\r\n";
	code += "	f.write('\\nclass LCD16x2RGB(object):')" + "\r\n";
	code += "	f.write('\\n	i2cBus = I2C()')" + "\r\n";
	code += "	f.write('\\n	# BackLight Adr & Reg')" + "\r\n";
	code += "	f.write('\\n	BL_ADDR         = 0x62')" + "\r\n";
	code += "	f.write('\\n	BL_MD1_REG      = 0x00')" + "\r\n";
	code += "	f.write('\\n	BL_MD2_REG      = 0x01')" + "\r\n";
	code += "	f.write('\\n	BL_BLUE_REG     = 0x02')" + "\r\n";
	code += "	f.write('\\n	BL_GREEN_REG    = 0x03')" + "\r\n";
	code += "	f.write('\\n	BL_RED_REG      = 0x04')" + "\r\n";
	code += "	f.write('\\n	BL_OUT_REG      = 0x08')" + "\r\n";
	code += "	f.write('\\n	# LCD Adr & Reg')" + "\r\n";
	code += "	f.write('\\n	LCD_ADDR = 0x3E')" + "\r\n";
	code += "	f.write('\\n	LCD_CLEARDISPLAY = 0x01')" + "\r\n";
	code += "	f.write('\\n	LCD_RETURNHOME = 0x02')" + "\r\n";
	code += "	f.write('\\n	LCD_ENTRYMODESET = 0x04')" + "\r\n";
	code += "	f.write('\\n	LCD_DISPLAYCONTROL = 0x08')" + "\r\n";
	code += "	f.write('\\n	LCD_FUNCTIONSET = 0x20')" + "\r\n";
	code += "	f.write('\\n	LCD_ENTRYLEFT = 0x02')" + "\r\n";
	code += "	f.write('\\n	LCD_ENTRYSHIFTINCREMENT = 0x01')" + "\r\n";
	code += "	f.write('\\n	LCD_ENTRYSHIFTDECREMENT = 0x00')" + "\r\n";
	code += "	f.write('\\n	LCD_DISPLAYON = 0x04')" + "\r\n";
	code += "	f.write('\\n	LCD_CURSORON = 0x02')" + "\r\n";
	code += "	f.write('\\n	LCD_CURSOROFF = 0x00')" + "\r\n";
	code += "	f.write('\\n	LCD_BLINKON = 0x01')" + "\r\n";
	code += "	f.write('\\n	LCD_BLINKOFF = 0x00')" + "\r\n";
	code += "	f.write('\\n	LCD_2LINE = 0x08')" + "\r\n";
	code += "	f.write('\\n	def __init__(self):')" + "\r\n";
	code += "	f.write('\\n		if self.i2cBus.is_ready(self.LCD_ADDR) is not True :')" + "\r\n";
	code += "	f.write('\\n			raise Exception(\\'I2C : device not responding\\')')" + "\r\n";
	code += "	f.write('\\n		# LCD Init')" + "\r\n";
	code += "	f.write('\\n		self.disp_func = self.LCD_DISPLAYON | self.LCD_2LINE')" + "\r\n";
	code += "	f.write('\\n		delay(50)')" + "\r\n";
	code += "	f.write('\\n		self.writeReg(self.LCD_ADDR,0x80,self.LCD_FUNCTIONSET | self.disp_func)')" + "\r\n";
	code += "	f.write('\\n		udelay(4500)')" + "\r\n";
	code += "	f.write('\\n		self.writeReg(self.LCD_ADDR,0x80,self.LCD_FUNCTIONSET | self.disp_func)')" + "\r\n";
	code += "	f.write('\\n		udelay(150)')" + "\r\n";
	code += "	f.write('\\n		self.writeReg(self.LCD_ADDR,0x80,self.LCD_FUNCTIONSET | self.disp_func)')" + "\r\n";
	code += "	f.write('\\n		self.disp_ctrl = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF')" + "\r\n";
	code += "	f.write('\\n		self.display(True)')" + "\r\n";
	code += "	f.write('\\n		self.clear()')" + "\r\n";
	code += "	f.write('\\n		self.disp_mode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT')" + "\r\n";
	code += "	f.write('\\n		self.writeReg(self.LCD_ADDR,0x80,self.LCD_ENTRYMODESET | self.disp_mode)')" + "\r\n";
	code += "	f.write('\\n		# BackLight Init')" + "\r\n";
	code += "	f.write('\\n		self.writeReg(self.BL_ADDR,self.BL_MD1_REG,0x00)')" + "\r\n";
	code += "	f.write('\\n		self.writeReg(self.BL_ADDR,self.BL_MD2_REG,0x00)')" + "\r\n";
	code += "	f.write('\\n		self.writeReg(self.BL_ADDR,self.BL_OUT_REG,0xAA)')" + "\r\n";
	code += "	f.write('\\n	def writeReg(self,devAdr,regAdr,val):')" + "\r\n";
	code += "	f.write('\\n		dta = bytearray([regAdr,val])')" + "\r\n";
	code += "	f.write('\\n		self.i2cBus.send(dta,addr=devAdr)')" + "\r\n";
	code += "	f.write('\\n	def write_char(self, c):')" + "\r\n";
	code += "	f.write('\\n		assert c >= 0 and c < 256')" + "\r\n";
	code += "	f.write('\\n		c = bytearray([int(c)])')" + "\r\n";
	code += "	f.write('\\n		self.i2cBus.mem_write(c,self.LCD_ADDR, 0x40)')" + "\r\n";
	code += "	f.write('\\n	def print(self, text):')" + "\r\n";
	code += "	f.write('\\n		for char in text:')" + "\r\n";
	code += "	f.write('\\n			self.write_char(ord(char))')" + "\r\n";
	code += "	f.write('\\n	def cursor(self, state):')" + "\r\n";
	code += "	f.write('\\n		if state:')" + "\r\n";
	code += "	f.write('\\n			self.disp_ctrl |= self.LCD_CURSORON')" + "\r\n";
	code += "	f.write('\\n			self.writeReg(self.LCD_ADDR,0x80,self.LCD_DISPLAYCONTROL  | self.disp_ctrl)')" + "\r\n";
	code += "	f.write('\\n		else:')" + "\r\n";
	code += "	f.write('\\n			self.disp_ctrl &= ~self.LCD_CURSORON')" + "\r\n";
	code += "	f.write('\\n			self.writeReg(self.LCD_ADDR,0x80,self.LCD_DISPLAYCONTROL  | self.disp_ctrl)')" + "\r\n";
	code += "	f.write('\\n	def setCursor(self, col, row):')" + "\r\n";
	code += "	f.write('\\n		col = (col | 0x80) if row == 0 else (col | 0xc0)')" + "\r\n";
	code += "	f.write('\\n		self.writeReg(self.LCD_ADDR,0x80,col)')" + "\r\n";
	code += "	f.write('\\n	def blink(self, state):')" + "\r\n";
	code += "	f.write('\\n		if state:')" + "\r\n";
	code += "	f.write('\\n			self.disp_ctrl |= self.LCD_BLINKON')" + "\r\n";
	code += "	f.write('\\n			self.writeReg(self.LCD_ADDR,0x80,self.LCD_DISPLAYCONTROL  | self.disp_ctrl)')" + "\r\n";
	code += "	f.write('\\n		else:')" + "\r\n";
	code += "	f.write('\\n			self.disp_ctrl &= ~self.LCD_BLINKON')" + "\r\n";
	code += "	f.write('\\n			self.writeReg(self.LCD_ADDR,0x80,self.LCD_DISPLAYCONTROL  | self.disp_ctrl)')" + "\r\n";
	code += "	f.write('\\n	def display(self, state):')" + "\r\n";
	code += "	f.write('\\n		if state:')" + "\r\n";
	code += "	f.write('\\n			self.disp_ctrl |= self.LCD_DISPLAYON')" + "\r\n";
	code += "	f.write('\\n			self.writeReg(self.LCD_ADDR,0x80,self.LCD_DISPLAYCONTROL  | self.disp_ctrl)')" + "\r\n";
	code += "	f.write('\\n		else:')" + "\r\n";
	code += "	f.write('\\n			self.disp_ctrl &= ~self.LCD_DISPLAYON')" + "\r\n";
	code += "	f.write('\\n			self.writeReg(self.LCD_ADDR,0x80,self.LCD_DISPLAYCONTROL  | self.disp_ctrl)')" + "\r\n";
	code += "	f.write('\\n	def clear(self):')" + "\r\n";
	code += "	f.write('\\n		self.writeReg(self.LCD_ADDR,0x80,self.LCD_CLEARDISPLAY)')" + "\r\n";
	code += "	f.write('\\n		delay(2)')" + "\r\n";
	code += "	f.write('\\n	def home(self):')" + "\r\n";
	code += "	f.write('\\n		self.writeReg(self.LCD_ADDR,0x80,self.LCD_RETURNHOME)')" + "\r\n";
	code += "	f.write('\\n		delay(2)')" + "\r\n";
	code += "	f.write('\\n	def setColor(self,r,g,b):')" + "\r\n";
	code += "	f.write('\\n		self.writeReg(self.BL_ADDR,self.BL_RED_REG,r)')" + "\r\n";
	code += "	f.write('\\n		self.writeReg(self.BL_ADDR,self.BL_GREEN_REG,g)')" + "\r\n";
	code += "	f.write('\\n		self.writeReg(self.BL_ADDR,self.BL_BLUE_REG,b)')" + "\r\n";
	code += "	f.write('\\n		# End I2C LCD 16x2 RGB Driver')" + "\r\n";
	code += "	f.close()" + "\r\n";
	code += "except:	print('lib already exist')" + "\r\n";
	if ( !ppy.isInRAWReplMode() )
		ppy.enterRawRepl().then( _ =>{		
			return ppy.exec(code);	
		});	
	else
		 return ppy.exec(code);	
}
function ImportLibRanger(){
	var code ="";
	code += "try:" + "\r\n";
	code += "	f = open('lib/USRanger.py', 'x')" + "\r\n";
	code += "	f.close()" + "\r\n";
	code += "	f = open('lib/USRanger.py', 'w')" + "\r\n";
	code += "	f.write('\\n# Begin Ultrasonic Ranger Driver')" + "\r\n";
	code += "	f.write('\\n# Work with :')" + "\r\n";
	code += "	f.write('\\n# - Grove - Ultrasonic Ranger')" + "\r\n";
	code += "	f.write('\\n#   AKA Sciencethic 651 014')" + "\r\n";
	code += "	f.write('\\n# - Sciencethic 651 049')" + "\r\n";
	code += "	f.write('\\nfrom ppy import Pin')" + "\r\n";
	code += "	f.write('\\nfrom ppy import udelay')" + "\r\n";
	code += "	f.write('\\nimport time')" + "\r\n";
	code += "	f.write('\\nclass USRanger(object):')" + "\r\n";
	code += "	f.write('\\n	def __init__(self,pinInit):')" + "\r\n";
	code += "	f.write('\\n		self.pin = pinInit')" + "\r\n";
	code += "	f.write('\\n	def mesureEchoMicrosSec(self):')" + "\r\n";
	code += "	f.write('\\n		self.pin.init(mode=Pin.OUT)')" + "\r\n";
	code += "	f.write('\\n		self.pin.low()')" + "\r\n";
	code += "	f.write('\\n		udelay(2)')" + "\r\n";
	code += "	f.write('\\n		self.pin.high()')" + "\r\n";
	code += "	f.write('\\n		udelay(5)')" + "\r\n";
	code += "	f.write('\\n		self.pin.low()')" + "\r\n";
	code += "	f.write('\\n		self.pin.init(mode=Pin.IN)')" + "\r\n";
	code += "	f.write('\\n		return self.pulseIn()')" + "\r\n";
	code += "	f.write('\\n	def mesureCentimeters(self):')" + "\r\n";
	code += "	f.write('\\n		return round((self.mesureEchoMicrosSec()/29/2),2)')" + "\r\n";
	code += "	f.write('\\n	def mesureInches(self):')" + "\r\n";
	code += "	f.write('\\n		return round((self.mesureEchoMicrosSec()/74/2),3)')" + "\r\n";
	code += "	f.write('\\n	def pulseIn(self,timeout=1000000):')" + "\r\n";
	code += "	f.write('\\n		begin = time.ticks_us()')" + "\r\n";
	code += "	f.write('\\n		while ( self.pin.value() is 1 ):')" + "\r\n";
	code += "	f.write('\\n			if ( time.ticks_us() - begin ) >= timeout :')" + "\r\n";
	code += "	f.write('\\n				return 0')" + "\r\n";
	code += "	f.write('\\n		while ( self.pin.value() is 0 ):')" + "\r\n";
	code += "	f.write('\\n			if ( time.ticks_us() - begin ) >= timeout :')" + "\r\n";
	code += "	f.write('\\n				return 0')" + "\r\n";
	code += "	f.write('\\n		pulseBegin = time.ticks_us()')" + "\r\n";
	code += "	f.write('\\n		while ( self.pin.value() is 1 ):')" + "\r\n";
	code += "	f.write('\\n			if ( time.ticks_us() - begin ) >= timeout :')" + "\r\n";
	code += "	f.write('\\n				return 0')" + "\r\n";
	code += "	f.write('\\n		pulseEnd = time.ticks_us()')" + "\r\n";
	code += "	f.write('\\n		return  ( pulseEnd - pulseBegin )')" + "\r\n";
	code += "	f.write('\\n# End Ultrasonic Ranger Driver')" + "\r\n";
	code += "	f.close()" + "\r\n";
	code += "except:	print('lib already exist')" + "\r\n";
	if ( !ppy.isInRAWReplMode() )
		ppy.enterRawRepl().then( _ =>{		
			return ppy.exec(code);	
		});	
	else
		 return ppy.exec(code);	
}
var checkboxvue = document.getElementsByClassName("vuechange");

for (var i = 0; i < checkboxvue.length; i++) {
    checkboxvue[i].addEventListener("change", function(){changeView()});
}

function closeMsg(){
	document.getElementById('FloatantMsg').style.display ="none"
}
function ShowAnnotation(msg, type){
	if(type == "ALERT"){
		document.getElementById('msgFloat').innerHTML = msg;
		document.getElementById('FloatantMsg').style.backgroundColor = "red";
		document.getElementById('FloatantMsg').style.display = "block";
	}else{
		document.getElementById('msgFloat').innerHTML = msg;
		document.getElementById('FloatantMsg').style.display = "block";
	}
	setTimeout(() => {
		closeMsg();
	}, 4000);

}


function themeChoix(theme) {
	if (theme == "black") {
		document.getElementById("whitetheme").checked = false;
		document.getElementById("csssheet").setAttribute("href", "css/main_blacktheme.css");
	} else if (theme == "white") {
		document.getElementById("blacktheme").checked = false;
		document.getElementById("csssheet").setAttribute("href", "css/main.css");
    }
}


function fitToscreen() {
	fit.fit();
	const dims = { cols: term.cols, rows: term.rows };
	}
	
	function debounce(func, wait_ms) {
	let timeout;
	return function (...args) {
	  const context = this;
	  clearTimeout(timeout);
	  timeout = setTimeout(() => func.apply(context, args), wait_ms);
	};
	}
	const wait_ms = 50;
	window.onresize = debounce(fitToscreen, wait_ms);

function handleReplMsg(event){
	if(userREPLInstalled){
		term.write(event);
	}
	
}
				
function replWriteMsg(msg){	
	if (!userREPLInstalled){	
		ppy.exitRawRepl(_ =>{
			ppy.sendString(msg);	
		});
	}else{
		ppy.sendString(msg);
	}	
}
var datas = [];
function isNumber(str) {
	var pattern = /^\d+$/;
	return pattern.test(str);  // returns a boolean
}

var stringtoREPL= "";
term.onData((data) => {
	ppy.sendString(data);
});
// Définir une variable pour suivre l'état de la vérification
var verificationTerminee = false;

this.ppy = new PlugPyCommunicator();

this.ppy.registerConnectionStateCallback(function(stateCode){
	
	switch(stateCode){
			
		// Connecting... / En connexion
		case PlugPyCommunicator.CONN_STATE_CONNECTING : {
			if (this.stateLabelElement != null)
				this.stateLabelElement.innerHTML = "Connecting...";
		} break;
		
		// Connected / Connecté
		case PlugPyCommunicator.CONN_STATE_CONNECTED : {
			document.getElementById('coBtn').classList.remove("shakeanim");
			ShowAnnotation("Appareil associé");
			setTimeout(() => {
				closeMsg();
			}, 5000);

			stateconnected = true;
			if (this.stateLabelElement != null)
				this.stateLabelElement.innerHTML = "Connected";
					
			if (this.connectionButton != null)
				this.connectionButton.value = "Disconnect";	
				
			if(!ppy.isInRAWReplMode){
				verificationTerminee = false; // Réinitialiser l'état de la vérification
			}

			ppy.enterRawRepl().then(function(res){	
				initPPy();
				setTimeout(() => {
					ImportLibAfficheur();
					setTimeout(() => {
						ImportLibTone();
						setTimeout(() => {
							ImportLibI2C();
							setTimeout(() => {
								ImportLibLCD();
								setTimeout(() => {
									ImportLibRanger();
									verificationTerminee = true; // Marquer la vérification comme terminée
									ShowAnnotation("Vérification des librairies terminée")
								}, 1400);
							}, 1400);
						}, 1400);
					}, 1400);
				}, 1400);

				ppy.registerRXRAWCb(function(rawStrIn){
					term.write(rawStrIn);		
					GrosChiffrePushData(rawStrIn);
				});		
			});
		} break;
		
		// Disconnected / deconnecté
		case PlugPyCommunicator.CONN_STATE_DISCONNECTED : {
			stateconnected = false;
			document.getElementById('coBtn').classList.add("shakeanim");
			if (this.stateLabelElement != null)
				this.stateLabelElement.innerHTML = "Disconnected";
					
			if (this.connectionButton != null)
				this.connectionButton.value = "Connect";
		} break;
		
		case PlugPyCommunicator.STATE_BUSY: {
			document.getElementById("BS_Background").style.display = "block";
			document.getElementById("loader").style.display = "block";
		} break;
		
		case PlugPyCommunicator.STATE_IDLE: {
			// Vérifier si la vérification est terminée
			if (verificationTerminee) {
				document.getElementById("BS_Background").style.display = "none";
				document.getElementById("loader").style.display = "none";
			} else {
				// Laisser le loader affiché si la vérification n'est pas terminée
				document.getElementById("BS_Background").style.display = "block";
				document.getElementById("loader").style.display = "block";
			}
		} break;
		
		default : 
			// console.log("unhandled connection state (stateCode : "+stateCode+")");
	}
});

window.onbeforeunload = function(event)
{
	if ( ppy.isInRAWReplMode() ){
		ppy.exitRawRepl(function(){
			ppy.sendCtrlKey(0x03);
		});				
	}else{
		ppy.sendCtrlKey(0x03);
	}	
	// ppy.disconnect();
};

function tryGrosChiffreParseJson(inVal){	
    outJsonParse = null;
	try {
		outJsonParse = JSON.parse(inVal);
	}catch(Err){
		outJsonParse = []
	}
	return outJsonParse;	
}

function openHelpPanel(){
	document.getElementById('BS_Background').style.display = "block";
	document.getElementById('HelpPanel').style.display = "block";
}
function closeHelpPanel(){
	document.getElementById('helpvid').pause();
	document.getElementById('BS_Background').style.display = "none";
	document.getElementById('HelpPanel').style.display = "none";
}

document.getElementById("blocklyDiv").addEventListener('resize', function(event){
	Blockly.svgResize(workspace);
});

function connectionPPY() {
	// if (ConnectionType == false) {
	// 	console.warn("TODO BLE CONNECTION");
	// } else if (ConnectionType == true) {
	// 	console.warn("TODO USB CONNECTION");
    // }
    ppy.connectDisconnect();
    
}
document.getElementById('ConBtn').addEventListener('click', connectionPPY);


function initPPy() {
	var cmd = "";	
	cmd += "import os" + "\r\n";
	cmd += "try :" + "\r\n";
	cmd += "    os.mkdir('\\Projet')" + "\r\n";
	cmd += "except : print('\\nFolder Projet already exist')" + "\r\n";
	if ( !ppy.isInRAWReplMode() )
		ppy.enterRawRepl().then( _ =>{		
			return ppy.exec(cmd);	
		});	
	else
		return ppy.exec(cmd);	
}


var fullscreen = false;
function HandleView(viewclick, idclicked){
	console.log(document.getElementById(idclicked));
	var v = document.getElementById(idclicked).childNodes[1].getAttribute("src");
			// if (document.getElementById(idclicked).src != "ressource/svg/003-fenetre.svg"){
			if (v != "ressource/svg/003-fenetre.svg"){
				// document.getElementById(idclicked).src = "ressource/svg/003-fenetre.svg";
				v = "ressource/svg/003-fenetre.svg";
				fullscreen = true;
				MaximizeView(viewclick);
				editor.refresh();
				// reInitChart();

			}else{
				// document.getElementById(idclicked).innerHTML = "🗖";
				// document.getElementById(idclicked).src = "ressource/svg/002-agrandir-la-fenetre.svg";
				v = "ressource/svg/002-agrandir-la-fenetre.svg";
				fullscreen = false;
				ResizeView(viewclick);	
				editor.refresh();
				// reInitChart();

			}
		document.getElementById(idclicked).childNodes[1].setAttribute("src", v);

}

function Save(){

}

function MaximizeView(viewclick){
	var ParentViewContainer = document.getElementById('Views');
	ParentViewContainer.childNodes.forEach(element => {
		if(element.id != undefined){
			if(element.id != viewclick){
				element.style.display = "none";
			}
			
			if(viewclick == "editor"){
				document.querySelector(".CodeMirror").style.height = "87vh"
			}
			if(viewclick == "Blockly"){
				Blockly.svgResize(workspace);
			}
			
		}
		
	});
}
function ResizeView(viewclick){
	let ContainerofcheckboxContainer = document.getElementById("dropdownVue");
	if(viewclick == "Blockly"){
		Blockly.svgResize(workspace);
	}
	ContainerofcheckboxContainer.childNodes.forEach(element => {
		if(element.id != undefined){
			let checkboxContainer = element;
			checkboxContainer.childNodes.forEach(element2 => {
				if(element2.type == "checkbox"){
					if(element2.checked){
						document.getElementById(element2.name).style.display = "block";
					}else{
						document.getElementById(element2.name).style.display = "none";
					}	
				}
			});
			
		}
	});
	Blockly.svgResize(workspace);
	

	// InitGrosChiffre();
	// initChartConf();
}

function OpenPref(){
	document.getElementById("PrefMenu").style.display ="block";
}
function fermerPref(view){
	if(view == "pref"){
		document.getElementById("PrefMenu").style.display ="none";
	}
	
}

function FermerVueActive(view){
	document.getElementsByName(view).forEach(element => {
		if(element.type == "checkbox"){
			element.checked = false;
		}
	});
	document.getElementById(view).style.display = "none";
	if(view != "Blockly"){
		Blockly.svgResize(workspace);
	}

}
function AfficheNavig(){
	document.getElementById('BS_Background').style.display = "block";
	if(stateconnected == true){
		document.getElementById('NavigationChoixMenu').style.display = "block";
		// document.getElementById('ChoixPlugPy').style.display = "block";
	}else {
		document.getElementById('NavigationChoixMenu').style.display = "block";
		document.getElementById('ChoixPlugPy').style.display = "none";
	}
}
function FermerOptionNavig(){
	document.getElementById('NavigationChoixMenu').style.display = "none";
	document.getElementById('BS_Background').style.display = "none";
}
function FermerNavig(){
    document.getElementById('NavFileContainer').style.display = "none";
	document.getElementById('NavFile').style.display = "none";

}
function displayFileContent(res){
	ppyFileSystem.displayContent(res);
 }
 
 var OpenProjet = false;
//  document.getElementById('refreshFSTress').addEventListener('click', function(){
// 		 ppyFileSystem.refreshFileContent(displayFileContent);
// 		 ppyFileSystem.reloadFsContent();
//  });
var currenFilePath = "";
function OpenOnPPY(){
	FermerOptionNavig();
	OpenProjetPanel();
	
}
function FermerSLocal(){
	document.getElementById("BS_Background").style.display = "none";
	document.getElementById("SLocalMenu").style.display = "none";
}
function OpenInLocal(){
	FermerOptionNavig();
	document.getElementById("BS_Background").style.display = "block";
	document.getElementById("SLocalMenu").style.display = "block";
}
function OpenProjetPanel(){
	document.getElementById("NavFile").style.display = "block";
	document.getElementById("NavFileContainer").style.display = "block";
	setTimeout(() => {
		document.getElementById("refreshFSTress").click();
	}, 200);
}
function BackProjet(){
	document.getElementById("formNewProjet").style.display = "none";
	document.getElementById("BS_Background").style.display = "none";
}
function OpenNewProjet(){
	document.getElementById('NavigationLocalMenu').style.display = "none"
	// document.getElementById('BS_Background').style.display = "block";
	document.getElementById('formNewProjet').style.display = "block";
	
}
function submitForm(){
	if(document.getElementById('NamProjet').value != ""){
		projetName = document.getElementById('NamProjet').value;
		currenFilePath = projetName;
		// SaveProjet();
		// this.ppyFileSystem.NewProjet(projetName);
		// SaveProjet();
		// SaveInFile();
		Saveblk();
		document.getElementById('BS_Background').style.display = "none";
		document.getElementById('formNewProjet').style.display = "none";
	}else {
		window.alert("Veuillez remplir le champ vide !")
	}
}
 
var OpenProjet = false;
//  document.getElementById('refreshFSTress').addEventListener('click', function(){
// 		 ppyFileSystem.refreshFileContent(displayFileContent);
// 		 ppyFileSystem.reloadFsContent();
//  });
var currenFilePath = "";
function OpenOnPPY(){
	FermerOptionNavig();
	OpenProjetPanel();
	
}
function FermerNavigLocal(){
	document.getElementById("BS_Background").style.display = "none";
	document.getElementById("NavigationLocalMenu").style.display = "none";
}
function OpenInLocal(){
	FermerOptionNavig();
	document.getElementById("BS_Background").style.display = "block";
	document.getElementById("NavigationLocalMenu").style.display = "block";
}
function OpenProjetPanel(){
	document.getElementById("NavFile").style.display = "block";
	document.getElementById("NavFileContainer").style.display = "block";
	setTimeout(() => {
		document.getElementById("refreshFSTress").click();
	}, 200);
}
function BackProjet(){
	document.getElementById("formNewProjet").style.display = "none";
	document.getElementById("BS_Background").style.display = "none";
}
function OpenNewProjet(){
	document.getElementById('NavigationLocalMenu').style.display = "none"
	// document.getElementById('BS_Background').style.display = "block";
	document.getElementById('formNewProjet').style.display = "block";
	
}
function submitForm(){
	if(document.getElementById('NamProjet').value != ""){
		projetName = document.getElementById('NamProjet').value;
		currenFilePath = projetName;
		// SaveProjet();
		// this.ppyFileSystem.NewProjet(projetName);
		// SaveProjet();
		// SaveInFile();
		Saveblk();
		document.getElementById('BS_Background').style.display = "none";
		document.getElementById('formNewProjet').style.display = "none";
	}else {
		window.alert("Veuillez remplir le champ vide !")
	}
}
var newProjetName;

function requestFsContent(fsContentCB){
	var cmd = "";	
	cmd += "import json" + "\r\n";
	cmd += "from os import ilistdir" + "\r\n";
	cmd += "def listFsElement(path,filterTypeFile) : " + "\r\n";
	cmd += "    res = []" + "\r\n";
	cmd += "    try : " + "\r\n";
	cmd += "        for fsItem in ilistdir(path) : " + "\r\n";
	
	// if (this.appPref[prefIndexBolOnlyDisplayPythonExecutableFiles]){
		// cmd += "            if filterTypeFile and fsItem[1] == 0x8000 and \".py\" in fsItem[0] : " + "\r\n";
	// }else{
	cmd += "            if filterTypeFile and fsItem[1] == 0x8000 : " + "\r\n";
	// }
	cmd += "                res.append(fsItem[0])" + "\r\n";
	cmd += "            elif not(filterTypeFile) and fsItem[1] != 0x8000 : " + "\r\n";
	// if (this.appPref[prefIndexBolHideSystemFilesFolders]){
		// cmd += "                if \"System Volume Information\" not in fsItem[0] and \"conf\" not in fsItem[0] : " + "\r\n";
	// }else{
	// cmd += "                if \"System Volume Information\" not in fsItem[0] and \"Fichier Recent\" not in fsItem[0] : " + "\r\n";
	cmd += "                if \"System Volume Information\" not in fsItem[0] and \"TP\" not in fsItem[0] and \"conf\" not in fsItem[0] and \"lib\" not in fsItem[0]  and \"MiscTools\" not in fsItem[0]: " + "\r\n";
	// }	
	cmd += "                    res.append(fsItem[0])" + "\r\n";
	cmd += "    except : pass" + "\r\n";
	cmd += "    return res" + "\r\n";
	cmd += "def discoverFs(out,currentPath) : " + "\r\n";		
	cmd += "    out += listFsElement(currentPath,True)" + "\r\n";
	cmd += "    for folderName in listFsElement(currentPath,False) : " + "\r\n";
	cmd += "        tempDirContent = [folderName] " + "\r\n";
	cmd += "        if currentPath != \"\" : " + "\r\n";
	cmd += "            folderName = '/'+folderName" + "\r\n";
	cmd += "        discoverFs(tempDirContent,currentPath+folderName)" + "\r\n";
	cmd += "        out.append(tempDirContent)" + "\r\n";
	cmd += "fsElement = []" + "\r\n";
	cmd += "discoverFs(fsElement,\"\")" + "\r\n";
	cmd += "print(json.dumps(fsElement))" + "\r\n";
	if ( !ppy.isInRAWReplMode() )
		ppy.enterRawRepl().then(function(res){		
			ppy.exec(cmd).then(function(res){		
				tryParseFsAnswer(res,fsContentCB);
			});
			
		});	
	else
		ppy.exec(cmd).then(function(res){
			tryParseFsAnswer(res,fsContentCB);

		});

}
function removeFolder(folderPath,cbDone=null){
	var cmd = "";	
	cmd += "from os import ilistdir,remove,rmdir" + "\r\n";
	cmd += "def discoverFoldersRemoveFiles(tmp,folders,folderPath) :" + "\r\n";
	cmd += "	res = []" + "\r\n";
	cmd += "	for fsItem in ilistdir(folderPath) :" + "\r\n";
	cmd += "		if fsItem[1] == 0x8000 :" + "\r\n";
	cmd += "			remove(folderPath+\"/\"+fsItem[0])" + "\r\n";
	cmd += "		elif fsItem[1] != 0x8000 :" + "\r\n";
	cmd += "			res.append(fsItem[0])" + "\r\n";
	cmd += "	for folderName in res :" + "\r\n";
	cmd += "		tempDirContent = [folderName]" + "\r\n"; 
	cmd += "		folderName = \"/\"+folderName" + "\r\n";
	cmd += "		discoverFoldersRemoveFiles(tempDirContent,folders,folderPath+folderName)" + "\r\n";
	cmd += "		folders.append(folderPath+folderName)" + "\r\n";
	cmd += "		tmp.append(folderName)" + "\r\n";
	cmd += "tmp = []" + "\r\n";
	cmd += "folders = []" + "\r\n";
	cmd += "discoverFoldersRemoveFiles(tmp,folders,\""+folderPath.substr(1)+"\")" + "\r\n";
	cmd += "for folderPath in folders :" + "\r\n";
	cmd += "	rmdir(folderPath)" + "\r\n";
	cmd += "rmdir(\""+folderPath.substr(1)+"\")" + "\r\n";
	if ( !ppy.isInRAWReplMode() )
		ppy.enterRawRepl().then(function(res){		
			ppy.exec(cmd).then(function(res){
				if (cbDone !=null)
					cbDone("OK");
			});
		});
	else
		ppy.exec(cmd).then(function(res){
			if (cbDone !=null)
				cbDone("OK");
		});
}
function makeFolder(folderPath,cbDone=null){
	var cmd = "";
	cmd += "import os" + "\r\n";
	cmd += "os.mkdir(\""+folderPath.substr(1)+"\")" + "\r\n";
	if ( !ppy.isInRAWReplMode() )
		ppy.enterRawRepl().then(function(res){		
			ppy.exec(cmd).then(function(res){
				if (cbDone !=null)
					cbDone("OK");
			});
		});
	else
		ppy.exec(cmd).then(function(res){
			if (cbDone !=null)
				cbDone("OK");
		});
}

var typeOuvert = "";

document.getElementById("OpenFileLocal").addEventListener("click", function () {
    document.getElementById("filelocal").click();
});

document.getElementById("filelocal").addEventListener("change", async function () {
    typeOuvert = "local";
    
    try {
        const fileInput = this;
        if (fileInput.files && fileInput.files.length > 0) {
            const extension = fileInput.files[0].name.substr(fileInput.files[0].name.lastIndexOf('.') + 1);
            console.log("File extension:", extension);

            document.getElementById("closectrlFile").style.display = "block";
            FermerNavigLocal();

            let text = await readFileAsync(fileInput.files[0]);

            if (extension === "blk") {
                loadBlocklyFile(text, fileInput.files[0].name);
            } else {
                loadPythonFile(text, fileInput.files[0].name);
            }
        } else {
            console.error("No file selected");
        }
    } catch (error) {
        console.error("Error handling file:", error.message);
    }
});

function loadBlocklyFile(text, fileName) {
    try {
        var xml = Blockly.Xml.textToDom(text);

        if (!workspace) {
            console.error("Blockly workspace not initialized");
            return;
        }

        workspace.clear();

        var blkFileElement = document.getElementById("BlkFile");
        if (blkFileElement) {
            blkFileElement.innerHTML = fileName;
        }

        Blockly.Xml.domToWorkspace(xml, workspace);
    } catch (error) {
        console.error("Error loading Blockly file:", error.message);
        console.error("File content:", text);
    }
}

function loadPythonFile(text, fileName) {
    try {
        var res = atob(text);
        editor.setValue(res);
        
        var pyFileElement = document.getElementById("PyFile");
        if (pyFileElement) {
            pyFileElement.innerHTML = fileName;
        }
    } catch (error) {
        console.error("Error decoding file:", error.message);
        editor.setValue(text);
    }
}

function readFileAsync(file) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();

        reader.onload = (event) => {
            resolve(event.target.result);
        };

        reader.onerror = (error) => {
            reject(error);
        };

        reader.readAsText(file);
    });
}

function CloseOpenFile() {
    document.getElementById("Saveinblk").style.display = "block";
    
    var pyFileElement = document.getElementById("PyFile");
    if (pyFileElement) {
        pyFileElement.innerHTML = "PyFile";
    }
    
    var closeCtrlFileElement = document.getElementById("closectrlFile");
    if (closeCtrlFileElement) {
        closeCtrlFileElement.style.display = "none";
    }

    editor.setValue("");
}


function CloseOpenFile() {
    document.getElementById("Saveinblk").style.display = "block";
    
    // Ajouter des vérifications pour éviter les erreurs si les éléments ne sont pas présents
    var pyFileElement = document.getElementById("PyFile");
    if (pyFileElement) {
        pyFileElement.innerHTML = "PyFile";
    }
    
    var closeCtrlFileElement = document.getElementById("closectrlFile");
    if (closeCtrlFileElement) {
        closeCtrlFileElement.style.display = "none";
    }

    editor.setValue("");
}




function removeFile(filePath,cbDone=null){
	var cmd = "";
	cmd += "import os" + "\r\n";
	cmd += "os.remove(\""+filePath.substr(1)+"\")" + "\r\n";
	if ( !ppy.isInRAWReplMode() )
		ppy.enterRawRepl().then(function(res){		
			ppy.exec(cmd).then(function(res){
				if (cbDone !=null)
					cbDone("OK");
			});
		});
	else
		ppy.exec(cmd).then(function(res){
			if (cbDone !=null)
				cbDone("OK");
		});
}
function _isPPYNativeFilePath(filePath){
	if (filePath.length){
		var extention = filePath.substr(filePath.lastIndexOf('.'),filePath.length);
		if (extention == ".py" && /[^a-z0-9_()]/i.test(filePath) && !filePath.includes(' '))
			return true;
	}
	console.warn("Unsopported file.");
	return false;
}
function _checkAndExecuteFile(executeFilePath){
	if (_isPPYNativeFilePath(executeFilePath))
		executeFile(executeFilePath.substr(0,executeFilePath.lastIndexOf('.')));
}
function editorExecuteCurrentFile(){
	_checkAndExecuteFile(currenFilePath);
}
function executeFile(filePath){
	filePath = filePath.substr(1).replace(/\//g,'.');
	var cmd = "";
	cmd += "print(\"\\r\\n\")" + "\r\n";
	cmd += "import "+filePath+"\r\n";
	ppy.enterRawRepl().then(function(){
		ppy.exec(cmd,false,true).then(function(res){
			ppy.exitRawRepl();
		});
	});
}
function _checkAndSetStartUpFile(startUpFilePath){
	if (_isPPYNativeFilePath(startUpFilePath))
		setStartupFile(startUpFilePath);
}
function editorSetStartupCurrentFile(){
	_checkAndSetStartUpFile(currenFilePath);
}
function setStartupFile(filePath){
	var cmd = "";
	cmd += "file = open(\"conf/startUpFile.py\",'w')" + "\r\n";
	cmd += "file.write(\"from ppy import main\\rmain(\\\""+filePath.substr(1)+"\\\")\")" + "\r\n";
	cmd += "file.close()" + "\r\n";
	if ( !ppy.isInRAWReplMode() )
		ppy.enterRawRepl().then(function(res){		
			ppy.exec(cmd).then(function(res){
				
			});
		});
	else
		ppy.exec(cmd).then(function(res){
			
		});
}
function renameFile(filePathToName,newName,cbDone){
	var newFilePath = filePathToName.substr(0,filePathToName.lastIndexOf('/')+1)+newName;
	var cmd = "";	
	cmd += "from os import rename" + "\r\n";
	cmd += "rename(\""+filePathToName.substr(1)+"\",\""+newFilePath.substr(1)+"\")" + "\r\n";
	if ( !ppy.isInRAWReplMode() )
		ppy.enterRawRepl().then(function(res){		
			ppy.exec(cmd).then(function(res){
				if (cbDone !=null)
					cbDone("OK");
			});
		});
	else
		ppy.exec(cmd).then(function(res){
			if (cbDone !=null)
				cbDone("OK");
		});
}
function loadFileCheckPrefSaveOpenedFile(nextFilePathToBeOpen,byPassCheckPrefSave=true,doneCb=null){
	// this.nextFilePathToBeOpen = nextFilePathToBeOpen;
	// if ( byPassCheckPrefSave == false && this.appPref[prefIndexBolPromptToSaveFileIfModifiefBeforeLoadingAnotherFile] && this.currentFileIsModified && currenFilePath != "" ){
		// document.getElementById ( "bgEditorSaveBeforeOpenAnotherFile" ).style.visibility = "visible";
		// if (doneCb != null)
			// doneCb(null);		
	// }else{
		// this.currentFileIsModified = false;
		// if (doneCb != null)
			doneCb("CONTINUE");
	// }
}
function loadFile(filePath,loadCB,readSizeBlock=512,writeFileHistoryPref=true,byPassCheckPrefSave=false,updateCurrentFilePath=true){
	loadFileCheckPrefSaveOpenedFile(filePath,byPassCheckPrefSave,function(res){
		if (res == "CONTINUE"){
			
			typeOuvert = "ppy";
			CloseProjet();

			// document.getElementById("Savepy").style.display = "block";
			document.getElementById("closectrlFile").style.display = "block";
			document.getElementById("closeCntl").style.display = "none";
			// document.getElementById("Saveinblk").style.display = "none";
			editor.setValue("")
			if (updateCurrentFilePath)
				currenFilePath = filePath;
			document.getElementById("PyFile").innerHTML = currenFilePath.substr(1);
			var cmd = "";
			cmd += "from lib.base64 import b64encode" + "\r\n";
			cmd += "from os import stat" + "\r\n";
			cmd += "try : " + "\r\n";
			cmd += "    res = stat(\""+filePath.substr(1)+"\")" + "\r\n";
			cmd += "    res = \"\"" + "\r\n";
			cmd += "    file = open(\""+filePath.substr(1)+"\",\"rb\")" + "\r\n";	
			cmd += "    res = file.read("+readSizeBlock.toString()+")" + "\r\n";
			cmd += "    while len(res) : " + "\r\n";
			cmd += "        print(b64encode(b''+res).decode())" + "\r\n";
			cmd += "        res = file.read("+readSizeBlock.toString()+")" + "\r\n";
			cmd += "    file.close()" + "\r\n";	
			cmd += "except : print(\"NULL\")" + "\r\n";
			if ( !ppy.isInRAWReplMode() )
				
				ppy.enterRawRepl().then(function(res){		
					ppy.exec(cmd).then(function(res){
						
						if (res.indexOf("NULL")==0){
							loadCB(null,null);
						}else{
							readFileModificationDateTime(filePath,function(fileModificationDate){					
								// if ( this.appPref[ prefIndexBolRestoreEditorLastView ] && writeFileHistoryPref == true ){
									// this.appPref[ prefIndexStrEditorLastViewPath ] = filePath;
									// readAndWriteGUIUseDefiniedSettings(function(res1){
										// rres = "";
										// res.split("\n").forEach(function(line){rres+=atob(line)});
										// loadCB(rres,fileModificationDate);
									// });
									
								// }else{
									 FichierOuvert = filePath;
									rres = "";
									if(res != ""){
										res.split("\n").forEach(function(line){rres+=atob(line)});
									}
									loadCB(rres,fileModificationDate);
								// }
							});		
						}
						FermerNavig();						
					});
				});
			else
				ppy.exec(cmd).then(function(res){
					editor.setValue("")		
					if (res.indexOf("NULL")==0){
							loadCB(null,null);
					}else{
						readFileModificationDateTime(filePath,function(fileModificationDate){					
							// if ( this.appPref[ prefIndexBolRestoreEditorLastView ] && writeFileHistoryPref == true ){
								// this.appPref[ prefIndexStrEditorLastViewPath ] = filePath;
								// readAndWriteGUIUseDefiniedSettings(function(res1){
										// rres = "";
										// res.split("\n").forEach(function(line){rres+=atob(line)});
										// loadCB(rres,fileModificationDate);
								// });
							// }else{
								rres = "";
								FichierOuvert = filePath;
								// try{
								// 	rrres = atob(line);
								// }catch(error){
									
								// 	/* TODO, gérer erreur */
								// 	console.warn("TODO, gérer erreur");
									
								// }
								
								
								if(res != ""){
									res.split("\n").forEach(function(line){rres+=atob(line)});
								}
								loadCB(rres,fileModificationDate);
							// }
						});		
					}
				});	
			FermerNavig();			
		}	
	});	

}

function readFileModificationDateTime(filePath,doneCB=null){
	cmd = "";				
	cmd += "import os" + "\r\n";
	cmd += "print(os.stat(\""+filePath.substr(1)+"\")[8])" + "\r\n";
	ppy.exec(cmd).then(function(fileModificationDate){
			if (doneCB != null)
				doneCB(new Date((parseInt(fileModificationDate)*1000)+946656000000).toLocaleString());
	});
}

this.ppyFileSystem = new PlugPyFileSystem("","",
	function(editFilePath){
		var extention = editFilePath.substr(editFilePath.lastIndexOf('.'),editFilePath.length);
		console.log(extention)
		if (extention == ".txt" || extention == ".htm" || extention == ".html" || extention == ".py" || extention == ".js" || extention == ".inf"|| extention == ".log"){
			loadFile(editFilePath,function(res,lastModificationDate){
				// mooveToEditor();
				// addTofichierRecent(editFilePath);
				if(res != null){
					editor.setValue(res);
				}
			
			// document.getElementById("currentFileUl").childNodes[1].innerText = editFilePath.substr(editFilePath.lastIndexOf('/')+1);
			// document.getElementById("currentFileUl").childNodes[3].innerText = lastModificationDate;setEditorPyFileBtnActionState(extention == ".py");
			});
		}else if(extention == ".blk"){
			loadFile(editFilePath,function(res,lastModificationDate){
				    // addTofichierRecent(editFilePath);
					if(res != null){
						xml_text = Blockly.Xml.domToText(xml);
						xml = Blockly.Xml.textToDom(xml_text);
						searchInXml(xml_text);
						workspace.clear();
						Blockly.Xml.domToWorkspace(xml, workspace);
					}
			});
		}else{
			console.warn("(to editor) Unsopported file format ("+extention+")");
			ShowAnnotation("Format non supporté", "ALERT");
			setTimeout(() => {
				closeMsg();
			}, 2000);
			
		}
	},
	function(){requestFsContent(function(res){ppyFileSystem.reloadFsContent(res);});},
	function(removeFilePath){removeFile(removeFilePath,function(res){requestFsContent(function(res){ppyFileSystem.reloadFsContent(res);});});},
	function(executeFilePath){_checkAndExecuteFile(executeFilePath);},
	function(startUpFilePath){_checkAndSetStartUpFile(startUpFilePath);},
	function(filePathToName,newName){renameFile(filePathToName,newName,function(res){requestFsContent(function(res){ppyFileSystem.reloadFsContent(res);if (filePathToName == currenFilePath){document.getElementById("currentFileUl").childNodes[1].innerText = newName;currenFilePath = filePathToName.substr(0,filePathToName.lastIndexOf('/')+1)+newName;}});});},
	function(removeFolderPath){removeFolder(removeFolderPath,function(res){requestFsContent(function(res){ppyFileSystem.reloadFsContent(res);});});},
	function(newFolderPath, cbDone=null){
		makeFolder(newFolderPath,function(res){
			requestFsContent(function(res){
				ppyFileSystem.reloadFsContent(res);
			});
		});
	},
	function(newFileAtPath, cbDone=null){
		// editor.setValue("# My new file, created on "+new Date().toLocaleString()+" .");
		currenFilePath = newFileAtPath;
		editorSaveCurrentFile(function(res){
			
			// var extention = newFileAtPath.substr(newFileAtPath.lastIndexOf('.'),newFileAtPath.length);
			// if (extention == ".txt" || extention == ".htm" || extention == ".html" || extention == ".py" || extention == ".js" || extention == ".inf" || extention == ".blk"){
				// loadFile(newFileAtPath,function(res,lastModificationDate){
					// editor.setValue(res);document.getElementById("currentFileUl").childNodes[1].innerText = newFileAtPath.substr(newFileAtPath.lastIndexOf('/')+1);
					// document.getElementById("currentFileUl").childNodes[3].innerText = lastModificationDate;
					// requestFsContent(function(res){ppyFileSystem.reloadFsContent(res);
					// });
				// });
			// }else 
			requestFsContent(function(res){
				ppyFileSystem.reloadFsContent(res);
			// }
			});
		},true);	
	},
	project_name => {
		currenFilePath = "/Projet/" + project_name;
		
		var cmd =
			"try:" + "\r\n"+ 
			"  import os" + "\r\n"+
			"  os.mkdir('Projet\\"+project_name+"')" + "\r\n"+
			"  file = open('Projet\\"+project_name+"\\"+project_name+".blk','w')" + "\r\n"+
			"  file.close()" + "\r\n"+
			"  file = open('Projet\\"+project_name+"\\"+project_name+".py','w')" + "\r\n"+
			"  file.close()" + "\r\n"+
			"except : print(\"Projet deja existant\")" + "\r\n";
					
		return ppy.exec(cmd);		
		
	},
	function(openprojetPath){
		OpenProjetWorkspace(openprojetPath, function(py, blk){
			currenFilePath = openprojetPath;
			document.getElementById("openFileCOntainer").innerHTML = "Projet : " + openprojetPath.substr(openprojetPath.lastIndexOf('/')+1);
			console.log(py)
			editor.setValue(py)
			importBlocks(blk)

		});
		
	}
);
function CloseProjet(){
	document.getElementById("openFileCOntainer").innerHTML = "Projet : ";
	document.getElementById("PyFile").innerHTML = "PyFile";
	document.getElementById("BlkFile").innerHTML = "BlkFile";
	document.getElementById("closeCntl").style.display = "none";

	editor.setValue("");
	workspace.clear();
	currenFilePath = "";
}function SaveProjet() {
    if (stateconnected == true) {
        let strFilePartPy = btoa(editor.getValue());

        var xml = Blockly.Xml.workspaceToDom(workspace);
        var xml_text = Blockly.Xml.domToText(xml);

        // Utiliser une chaîne vide comme espace de travail par défaut
        if (!xml_text.trim()) {
            xml_text = '';
        }

        let strFilePartBlk = btoa(xml_text);

        console.log(strFilePartBlk, xml_text);
        console.log(strFilePartPy, editor.getValue());

        if (currenFilePath != "") {
            var cmd = "";
            cmd += "file = open(\"" + currenFilePath.substr(1) + currenFilePath.substr(currenFilePath.lastIndexOf("/")) + ".py\",'w')" + "\r\n";
            cmd += "file.write('" + strFilePartPy + "')" + "\r\n";
            cmd += "file.close()" + "\r\n";
            cmd += "file = open(\"" + currenFilePath.substr(1) + currenFilePath.substr(currenFilePath.lastIndexOf("/")) + ".blk\",'w')" + "\r\n";
            cmd += "file.write(\"" + strFilePartBlk + "\")" + "\r\n";
            cmd += "file.close()" + "\r\n";
            console.log(cmd);

            if (!ppy.isInRAWReplMode()) {
                ppy.enterRawRepl().then(function (res) {
                    ppy.exec(cmd).then(function (res) {
                        // Traitement supplémentaire si nécessaire
                    });
                });
            } else {
                ppy.exec(cmd).then(function (res) {
                    // Traitement supplémentaire si nécessaire
                });
            }
        } else {
            OpenNewProjet();
        }

    } else {
        connectionPPY();
    }
}

function SaveInFile(){
	Saveblk();
	let strFilePart = btoa(editor.getValue()); 		
	if(typeOuvert == "local"){
		let filePath = filelocal.files[0].name;
		try { 
			var link = document.createElement('a');
			link.download= filePath;
			link.href="data:application/octet-stream;utf-8," + encodeURIComponent(editor.getValue());
			document.body.appendChild(link);
			link.click();
			link.remove();
		  } catch (e) {
			window.location.href="data:application/octet-stream;utf-8," + encodeURIComponent(editor.getValue());
			alert(e);
		  }
		
	}else{
		let filePath = FichierOuvert;
		var cmd = "";
		// cmd += "from lib.base64 import b64decode" + "\r\n";	
		cmd += "file = open(\""+filePath.substr(1)+"\",'w')" + "\r\n";	
		strFilePart = btoa(strFilePart);
		// cmd += "file.write(b64decode(\""+strFilePart+"\"))" + "\r\n";
		cmd += "file.write('"+strFilePart+"')" + "\r\n";
		cmd += "file.close()" + "\r\n";	
		
		console.warn(cmd);
		if ( !ppy.isInRAWReplMode() )
			ppy.enterRawRepl().then(function(res){		
				ppy.exec(cmd).then(function(res){
					
				});
			})
		else
			ppy.exec(cmd).then(function(res){
				
			});		
	}


	
}
function OpenProjetWorkspace(path, loadProjetCB, paquet = 64){

	document.getElementById("PyFile").innerHTML = path.substr(path.lastIndexOf("/")+1) + ".py";
	document.getElementById("BlkFile").innerHTML = path.substr(path.lastIndexOf("/")+1) + ".blk";
	// document.getElementById("Savepy").style.display = "none";
	document.getElementById("closectrlFile").style.display = "none";
	document.getElementById("closeCntl").style.display = "inline-block";
	document.getElementById("Saveinblk").style.display = "block";

	var code = "from lib.base64 import b64encode" + "\r\n";
	code += "from os import stat, ilistdir" + "\r\n";
	code += "try :" + "\r\n";
	code += "	path = \""+path.substr(1)+"\"" + "\r\n";
	code += "	resAll = \"\"" + "\r\n";
	code += "	for item in ilistdir(path):" + "\r\n";
	code += "		if \".blk\" in item[0] :" + "\r\n";
	code += "			pathItem = path + \"/\"+ item[0]" + "\r\n";
	// code += "			print(pathItem)" + "\r\n";
	code += "			resblk = stat(pathItem)" + "\r\n";
	code += "			resblk = \"\"" + "\r\n";
	code += "			file = open(pathItem,\"rb\")" + "\r\n";
	code += "			resblk = file.read("+paquet.toString()+")" + "\r\n";
	code += "			while len(resblk) :" + "\r\n";
	code += "				resAll += b64encode(b''+resblk).decode() + \"\\n\"" + "\r\n";
	// code += "				print(b64encode(b''+resblk).decode())" + "\r\n";
	code += "				resblk = file.read("+paquet.toString()+")" + "\r\n";
	code += "			file.close()" + "\r\n";
	code += "			resAll += \",\"" + "\r\n";
	code += "		if \".py\" in item[0]:" + "\r\n";
	code += "			pathItem = path + \"/\"+ item[0]" + "\r\n";
	// code += "			print(pathItem)" + "\r\n";
	code += "			res = stat(pathItem)" + "\r\n";
	code += "			res = \"\"" + "\r\n";
	code += "			file = open(pathItem,\"rb\")" + "\r\n";
	code += "			res = file.read("+paquet.toString()+")" + "\r\n";
	code += "			while len(res) :" + "\r\n";
	code += "				resAll += b64encode(b''+res).decode() + \"\\n\"" + "\r\n";
	code += "				res = file.read("+paquet.toString()+")" + "\r\n";
	code += "			file.close()" + "\r\n";
	code += "			print(resAll)" + "\r\n";
	code += "except : print(\"Erreur de lecture de fichier\")" + "\r\n";
	if ( !ppy.isInRAWReplMode() )
				
		ppy.enterRawRepl().then(function(res){		
			ppy.exec(code).then(function(res){
					editor.setValue("")		
			
					let respy = "";
					let ressblk = "";

					let blk = "";
					let py = "";
					FichierOuvert = "";
					if(res != ""){
						res.split(',').forEach(function(line){
							if(ressblk == ""){
								ressblk+= line
							}else{
								respy+= line
							}
						});
						ressblk.split("\n").forEach(function(line){blk+=atob(atob(line))});	
						respy.split("\n").forEach(function(line){py+=atob(atob(line))});						
					}	
					loadProjetCB(py,blk);
				FermerNavig();						
			});
		});
	else
	ppy.exec(code).then(function(res){
		editor.setValue("")		
		
				let respy = "";
				let ressblk = "";

				let blk = "";
				let py = "";
				FichierOuvert = "";
				if(res != ""){
					res.split(',').forEach(function(line){
						if(ressblk == ""){
							ressblk+= line
						}else{
							respy+= line
						}
					});
					console.log(ressblk, respy)
					ressblk.split("\n").forEach(function(line){blk+=atob(atob(line))});	
					respy.split("\n").forEach(function(line){py+=atob(atob(line))});						
				}
				
				loadProjetCB(py,blk);
		});	
	FermerNavig();

}


/////////////////////////////////////// ADD BLOCKLY ////////////////////////////////////////////

function importBlocks(xml_text) {
  try {
    // var xml_text = prompt("Please enter XML code", "");
    var xml = Blockly.Xml.textToDom(xml_text);
	searchInXml(xml_text);
    workspace.clear();
    Blockly.Xml.domToWorkspace(xml, workspace);
  } catch (e) {
    
  }
}	function Saveblk() {
    try {
        console.log(editor.getValue());
        var xml = Blockly.Xml.workspaceToDom(workspace);
        var xml_text = Blockly.Xml.domToText(xml);

        // Utiliser une chaîne vide comme espace de travail par défaut
        if (!xml_text.trim()) {
            xml_text = '';
        }

        var link = document.createElement('a');
        link.download = currenFilePath + ".blk";
        link.href = "data:application/octet-stream;utf-8," + encodeURIComponent(xml_text);
        document.body.appendChild(link);
        link.click();
        link.remove();

        var link_py = document.createElement('a');
        link_py.download = currenFilePath + ".py";
        link_py.href = "data:application/octet-stream;utf-8," + encodeURIComponent(editor.getValue());
        document.body.appendChild(link_py);
        link_py.click();
        link_py.remove();
    } catch (e) {
        window.location.href = "data:application/octet-stream;utf-8," + encodeURIComponent(xml_text);
        alert(e);
    }
}


var ppyBlocksSpe = [];
function autoecriture(event) {
  
	let outputCode = "";
	let imports = "";
	let inits = "";
  
	ppyBlocksSpe.forEach(function(dico){
	  		
		imports += "from "+dico.importLib+" import "+dico.importType+"\n";
		inits += dico.initBit+"\n";

	});
	  
	outputCode += imports +"\r\n";
	outputCode += inits +"\r\n";
	outputCode += Blockly.Python.workspaceToCode(workspace);
	
	editor.setValue(outputCode);
	
	
}
var xml = Blockly.Xml.workspaceToDom(workspace);
var xml_text = Blockly.Xml.domToText(xml);

workspace.addChangeListener(autoecriture);

function controlLib(event) {
	if(event.type == Blockly.Events.BLOCK_CREATE){
		var xml = new XMLSerializer().serializeToString(event.xml);
		if(xml.includes('oled')){
			let importLib = "ppy";
			let importType = "Oled";
			let initBit = "screen = Oled()"; 
			let strucProp = 
			{
				importLib:importLib,
				importType:importType,
				initBit:initBit
			};		
			checkForImport(strucProp);	
		}else if(xml.includes('delay')){
			let importLib = "ppy";
			let importType = "delay";
			let initBit = ""; 
			let strucProp = 
			{
				importLib:importLib,
				importType:importType,
				initBit:initBit
			};	
			checkForImport(strucProp);		
		}else if(xml.includes('switch')){
			let importLib = "ppy";
			let importType = "Switch";
			let initBit = "userSwitch = Switch()"; 
			let strucProp = 
			{
				importLib:importLib,
				importType:importType,
				initBit:initBit
			};		
			checkForImport(strucProp);
		}else if(xml.includes('lcd')){
			let importLib = "lib.LCD16x2RGB";
			let importType = "LCD16x2RGB as LCD";
			let initBit = "lcd = LCD()"; 
			let strucProp = 
			{
				importLib:importLib,
				importType:importType,
				initBit:initBit
			};	
			checkForImport(strucProp);
		}else if(xml.includes('milli')){
			let importLib = "ppy";
			let importType = "millis";
			let initBit = ""; 
			let strucProp = 
			{
				importLib:importLib,
				importType:importType,
				initBit:initBit
			};	
			checkForImport(strucProp);
		
		}else if(xml.includes("banane")){
			graphUpdateGraphTitle("Tension en fonction du temps");
			graphUpdateYaxesLeftTitle("Tension (en V)");
			InitTableur("Tension (en V)", "Temps (en ms)");

		}else if(xml.includes("aqcuisition_nbdonnee")){
			graphUpdateTimeLegeng("Temps (en s)");

		}else if(xml.includes("thermometre")){
			graphUpdateGraphTitle("Température en fonction du temps");
			graphUpdateYaxesLeftTitle("Température (en °C)");
			InitTableur("Température (en °C)", "Temps (en s)");

		}else if(xml.includes("station_co2")){

			graphUpdateGraphTitle("CO2 dans l'air en fonction du temps");
			graphUpdateYaxesLeftTitle("Particules par million (en PPM)");

		}else if(xml.includes("pression")){
			graphUpdateGraphTitle("Pression en fonction de 1 / Volume");
			graphUpdateYaxesLeftTitle("Pression (en hPa)");
			graphUpdateTimeLegeng("1 / Volume (mL)");
			InitTableur("Pression (en hPa)", "1 / Volume (mL)");

		}else if(xml.includes("exao_capteurtelemetre")){
			graphUpdateGraphTitle("Télemètre");
			graphUpdateYaxesLeftTitle("Distance (en m)");
			InitTableur("Distance (en m)", "Temps (en s)");			
		
		}else if(xml.includes("hydro")){
			graphUpdateGraphTitle("Pression en fonction de la profondeur");
			graphUpdateYaxesLeftTitle("Pression (en hPa)");
			graphUpdateTimeLegeng("Profondeur (en cm)");
			InitTableur("Pression (en hPa)", "Profondeur (en cm)");

		}else if(xml.includes("usranger")){
			graphUpdateGraphTitle("Temps de propagation des ultrasons en fonction d'une distance");
			graphUpdateYaxesLeftTitle("Distance (en m)");
			graphUpdateTimeLegeng("Temps de propagation (en s)");
			InitTableur("Distance (en m)", "Temps de propagation (en m)");
		}
		reInitChart();
	}else if(event.type == Blockly.Events.BLOCK_DELETE){
		var xml = new XMLSerializer().serializeToString(event.oldXml);
		var allblocks = new XMLSerializer().serializeToString(Blockly.Xml.workspaceToDom(workspace));	
		if(xml.includes('oled')){
			if(!allblocks.includes('oled')){
				var index = ppyBlocksSpe.indexOf(ppyBlocksSpe.find(strucProp => strucProp.importType === 'Oled'));
				ppyBlocksSpe.splice(index, 1);
			}

		}else if(xml.includes('delay')){
			if(!allblocks.includes('delay')){
				var index = ppyBlocksSpe.indexOf(ppyBlocksSpe.find(strucProp => strucProp.importType === 'delay'));
				ppyBlocksSpe.splice(index, 1);
			}

		}else if(xml.includes('lcd')){
			if(!allblocks.includes('lcd')){
				var index = ppyBlocksSpe.indexOf(ppyBlocksSpe.find(strucProp => strucProp.importType === 'lcd'));
				ppyBlocksSpe.splice(index, 1);
			}

		}else if(xml.includes('switch')){
			if(!allblocks.includes('switch')){
				var index = ppyBlocksSpe.indexOf(ppyBlocksSpe.find(strucProp => strucProp.importType === 'Switch'));
				ppyBlocksSpe.splice(index, 1);				
			}

		}else if (xml.includes('exao')){
			ReinitTableur(1);
			reInitChart();
			
		}else if (xml.includes('milli')){
			if(!allblocks.includes('milli')){
			var index = ppyBlocksSpe.indexOf(ppyBlocksSpe.find(strucProp => strucProp.importType === 'millis'));
			ppyBlocksSpe.splice(index, 1);				
		}
	}
	// graphUpdateGraphTitle("MyGraph");
	// graphUpdateYaxesLeftTitle("");
	// graphUpdateTimeLegeng(formatTimeAxisStr(samplingRate));
	graphConfig = initChartConf(
		title = formatTitle(null,null),		
		serieColor = [['rgb(255,0,0)',strYAxisLeft],['rgb(0,255,0)',strYAxisRight]],
		xAxisCaption = formatTimeAxisStr(samplingRate),
		gridLinesColor = "#dee6ef",
		leftYaxisCaption = strYAxisLeft,
		rightYaxisCaption = strYAxisRight,
		prevChartConf = null
	);
	reInitChart();
	InitGrosChiffre();
	}

}


workspace.addChangeListener(controlLib);
function searchInXml(xml_text){
	
	if(xml_text.includes('oled')){
		let importLib = "ppy";
		let importType = "Oled";
		let initBit = "screen = Oled()"; 
		let strucProp = 
		{
			importLib:importLib,
			importType:importType,
			initBit:initBit
		};	
		checkForImport(strucProp);		
	} 
	if(xml_text.includes('delay')){
		let importLib = "ppy";
		let importType = "delay";
		let initBit = ""; 	
		let strucProp = 
		{
			importLib:importLib,
			importType:importType,
			initBit:initBit
		};				
		checkForImport(strucProp);
	}
	if(xml_text.includes('switch')){
		let importLib = "ppy";
		let importType = "Switch";
		let initBit = "userSwitch = Switch()"; 
		let strucProp = 
		{
			importLib:importLib,
			importType:importType,
			initBit:initBit
		};	
		checkForImport(strucProp);
	}
	if(xml_text.includes('milli')){
		let importLib = "ppy";
		let importType = "millis";
		let initBit = ""; 
		let strucProp = 
		{
			importLib:importLib,
			importType:importType,
			initBit:initBit
		};	
		checkForImport(strucProp);		
	}
}


function checkForImport(struct){
	
	let found = false;
	
	if (ppyBlocksSpe.length){
		ppyBlocksSpe.forEach(
			function(dico){
				if( dico.importType == struct.importType ){
					found = true;
				}
			}
				
		);
		if (!found){
			ppyBlocksSpe.push(struct);
		}
	}else{
		ppyBlocksSpe.push(struct);
	}
	
}
var startTimer;
var stopRequested = false; // Variable pour marquer si un arrêt est demandé

function launchCode() {
    // Vérifie si un arrêt a été demandé, et si c'est le cas, affiche la boîte de dialogue
    if (stopRequested) {
        // Affichage de la boîte de dialogue
        document.getElementById('SLocalMenu').style.display = 'block';
        return; // Arrête l'exécution du reste de la fonction
    }

    // Le reste de votre logique actuelle pour lancer le code après la vérification d'arrêt
    if (ppy.isInRAWReplMode()) {
        ppy.exitRawRepl(function () {
            ppy.sendCtrlKey(0x03);
        });
    } else {
        ppy.sendCtrlKey(0x03);
    }
    
    setTimeout(() => {
        if (stateconnected == true) {
            if (!userREPLInstalled) {
                ppy.enterRawRepl().then(function () {
                    userREPLInstalled = false;

                    ppy.exec(editor.getValue(), false, true).then(function () {
                        startTimer = Date.now();
                    });
                });
            }
        } else {
            // displayConnectionPanel();
            connectionPPY();
        }
    }, 1000);
}

// Fonction pour réinitialiser le graphique lors de l'appel de "Relancer"
function relancer() {
    resetGraph();
    reInitChart();
    InitGrosChiffre();
    ReinitTableur();
	stopRequested = false;
	FermerSLocal();
}

function resetGraph() {
    // Ajout des étapes pour réinitialiser le graphique
    graphConfig = initChartConf(
        title = formatTitle(null, null),
        serieColor = [['rgb(255,0,0)', strYAxisLeft], ['rgb(0,255,0)', strYAxisRight]],
        xAxisCaption = formatTimeAxisStr(samplingRate),
        gridLinesColor = "#dee6ef",
        leftYaxisCaption = strYAxisLeft,
        rightYaxisCaption = strYAxisRight,
        prevChartConf = null
    );
    // Autres opérations de réinitialisation si nécessaires dans les prochaines versions
}
function enregistrer() {
	FermerSLocal();
    exportcsv(); // Appel de la fonction exportcsv() pour enregistrer les données
	stopRequested = false;
}


function StopProgram() {
    stopRequested = true; // Marque qu'un arrêt est demandé

    // logique pour arrêter le programme, sans effacer le code
    if (stateconnected == true) {
        if (ppy.isInRAWReplMode()) {
            ppy.exitRawRepl(function () {
                // Arrêter les composants sans effacer leur contenu
                ReinitTableur();
                ppy.sendCtrlKey(0x03);
            });
        } else {
            // Arrêter les composants sans effacer leur contenu
            ReinitTableur();
            ppy.sendCtrlKey(0x03);
        }
    } else {
        // displayConnectionPanel();
        connectionPPY();
    }
}


var readingState = 0;
var sharedGrosChiffreDataReq = ""
this.sharedDataReqSize = 4;


function tryParseFsAnswer(inStr,outCB){
	try{
		outCB(JSON.parse(inStr));
		
	}catch(err){
		console.warn("Unable to parse FS. answer ("+err+')');
	}
}
function strShift(shiftCount){
	res = sharedGrosChiffreDataReq.slice(0,shiftCount);
	sharedGrosChiffreDataReq = sharedGrosChiffreDataReq.slice(shiftCount,sharedGrosChiffreDataReq.length);
	return res;
}

function GrosChiffrePushData(data){
	handleReplMsg(data);
	sharedGrosChiffreDataReq += data;		
			while(sharedGrosChiffreDataReq.length){
				this.sharedDataReqSize = parseInt(strShift(2));
				if ( !isNaN(this.sharedDataReqSize) ){					
					if ( sharedGrosChiffreDataReq.length == this.sharedDataReqSize ){			
						partseData(sharedGrosChiffreDataReq);
						sharedGrosChiffreDataReq = "";						
					}else
						if ( sharedGrosChiffreDataReq.length < this.sharedDataReqSize )													
							readingState = 1;							
						else
							sharedGrosChiffreDataReq = "";											
					break;					
				}				
			}			
}

var counterLeg = 0;
var Unit = "";
var Valeur = "";
function InitGrosChiffre(){
	grosChiffrevue = document.getElementById('GrosChiffreView');
	// unitForGroschiffre = document.getElementById('unitGrosChiffre');
	// grosChiffrevue.style.fontFamily = "clock"
	grosChiffrevue.style.fontSize = '7em';
	grosChiffrevue.style.textAlign = 'center';
	grosChiffrevue.style.opacity = "0.3"
	grosChiffrevue.innerHTML = 8888.8;
	// unitForGroschiffre.style.textAlign = "center";
	// unitForGroschiffre.style.fontSize = "6.7em";
	// unitForGroschiffre.style.opacity = "0.3";
	// unitForGroschiffre.innerHTML = "...";
}

    
   


function GrosChiffreFeedData(unite, value){
	grosChiffrevue = document.getElementById('GrosChiffreView');
	str = value + " " + unite;
	grosChiffrevue.style.fontSize = '7em';
	grosChiffrevue.style.textAlign = 'center';
	grosChiffrevue.style.opacity = "1"
	grosChiffrevue.innerHTML = str;
	// unitForGroschiffre.style.textAlign = "center";
	// unitForGroschiffre.style.fontSize = "6.7em";
	// unitForGroschiffre.style.opacity = "1";
	// unitForGroschiffre.innerHTML = unite;
	
}
var msfromgraph = 0;
function partseData(data){
	try{
		res = tryGrosChiffreParseJson(JSON.parse(data))
		id = res[0];
		Unit = res[2];
		Valeur = res[1];

		InputUnit = res[4];
		InputValue = res[3];
		if(id == "8"){
			GrosChiffreFeedData(InputUnit, InputValue);
		}else{
			GrosChiffreFeedData(Unit, Valeur);
		}
		

			feedGraphDataSets(Valeur, InputValue);
			if(InputValue == "None"){
				FeedTableur(null, Valeur);
			}else{
				FeedTableur(InputValue, Valeur);
			}
		
		
	}catch(err){
		// console.warn("Erreur pars data  err : ",err);
	}
}

function setmsFromGraph(ms){
	msfromgraph += ms;	
}


/////////////////////////////////////// CHART CONF ///////////////////////////////////////////
const strBaseTitle = "";
const strBaseXAxisName = "";
let strYAxisLeft = "";
let strYAxisRight = "";
var samplingRate = 25;
var firsttimepass = 0;

function initgraphString(strTitle, strBasX, strYaxisLeft, strYaxisRight) {
    strBaseTitle = strTitle;
    strBaseXAxisName = strBasX;
    strYAxisLeft = strYaxisLeft;
    strYAxisRight = strYaxisRight;
    reInitChart();
}

function feedGraphDataSets(val, inputvalue) {
    graphConfig.options.scales.xAxes[0].ticks.beginAtZero = false;
    let dataSetCounter = 0;
    if (inputvalue != "None") {
        graphConfig.options.scales.yAxes[0].ticks.beginAtZero = false;
        graphConfig.data.datasets[dataSetCounter].data.push({
            x: inputvalue,
            y: val
        });
    } else {
        if (firsttimepass == 0) {
            firsttimepass = 1;
            graphConfig.data.datasets[0].data.push({
                x: 0,
                y: 0,
            });
        }
        graphConfig.data.datasets[dataSetCounter].data.push({
            x: (Date.now() - startTimer) / 1000,
            y: val,
        });
        setmsFromGraph(graphConfig.data.datasets[dataSetCounter].data[graphConfig.data.datasets[dataSetCounter].data.length - 1].x + 1);
    }
    dataSetCounter += 1;
    myLine.update();
}

var testt = 0;

function initChartConf(titleStr = null, serieData = null, xAxisCaption = null, gridLinesColor = "#dee6ef", leftYaxisCaption = null, rightYaxisCaption = null, prevChartConf = null) {
    var color = Chart.helpers.color;
    var chartConf = prevChartConf;
    if (prevChartConf == null) {
        chartConf = {
            type: 'line',
            data: {
                datasets: []
            },
            options: {
                showLines: false,
                responsive: true,
                maintainAspectRatio: false,
                title: {
                    display: false,
                    text: titleStr,
                    fontColor: "#dee6ef",
                },
                elements: {
                    point: {
                        pointStyle: "cross",
                        borderWidth: 2,
                        radius: 5,
                        backgroundColor: "#ff0000",
                    },
                    line: {
                        tension: "0",
                    },
                },
                scales: {
                    xAxes: [{
                        gridLines: {
                            color: gridLinesColor
                        },
                        type: 'linear',
                        display: true,
                        scaleLabel: {
                            display: true,
                            labelString: xAxisCaption,
                            fontColor: "#dee6ef"
                        },
                        ticks: {
                            stepSize: 1,
                            beginAtZero: false,
                            fontColor: "#dee6ef"
                        }
                    }],
                    yAxes: []
                },
                legend: {
                    display: false
                },
                animation: {
                    duration: 0
                },
                hover: {
                    animationDuration: 0
                },
                responsiveAnimationDuration: 0
            }
        };
    }
    if (titleStr != null)
        chartConf.options.title.display = true;

    if (leftYaxisCaption != null)
        chartConf.options.scales.yAxes.push({
            gridLines: {
                color: gridLinesColor
            },
            display: true,
            position: 'left',
            id: '0',
            scaleLabel: {
                display: true,
                labelString: leftYaxisCaption,
                fontColor: "#dee6ef",
            },
            ticks: {
                fontColor: "#dee6ef",
                suggestedMax: 1,
                suggestedMin: 0,
                beginAtZero: true
            }
        });


    if (rightYaxisCaption != null)
        chartConf.options.scales.yAxes.push({
            gridLines: {
                color: gridLinesColor
            },
            display: false,
            position: 'right',
            id: '1',
            scaleLabel: {
                display: false,
                labelString: rightYaxisCaption,
                fontColor: "#dee6ef",
            },
            ticks: {
                fontColor: "#dee6ef",
                suggestedMax: 1,
                suggestedMin: 0,
                beginAtZero: true
            }
        });

    if (serieData != null) {
        let labelAxisCounter = 0;
        serieData.forEach(function(data) {
            chartConf.data.datasets.push({
                hidden: false,
                label: data[1],
                yAxisID: String(labelAxisCounter),
                backgroundColor: color(data[0]).alpha(0.125 / 2).rgbString(),
                borderColor: data[0],
                fill: true,
            });
            labelAxisCounter++;
        });
    }


    return chartConf;
}

	// graphConfig.options.elements.line.tension = 0;
	
	function round(num, decimalPlaces = 0) {
		num = Math.round(Math.abs(num) + "e" + decimalPlaces) * Math.sign(num);
		return Number(num + "e" + -decimalPlaces);
	}
	
	var graphConfig = initChartConf(
		title = formatTitle(null,null),		
		serieColor = [['rgb(255,0,0)',strYAxisLeft],['rgb(0,255,0)',strYAxisRight]],
		xAxisCaption = formatTimeAxisStr(samplingRate),
		gridLinesColor = "#dee6ef",
		leftYaxisCaption = strYAxisLeft,
		rightYaxisCaption = strYAxisRight,
		prevChartConf = null
	);
	
	function formatTimeAxisStr(sampleRateValue){
		let ms = round(1/sampleRateValue,3);
		return "Temps (en s) ";
		// return strBaseXAxisName+" (n*"+String(ms)+" ms)";
	}

	
	function graphUpdateTimeLegeng(sampleRateValue){
		if(sampleRateValue != ""){
			graphConfig.options.scales.xAxes[0].scaleLabel.labelString = sampleRateValue;
		}else{
			graphConfig.options.scales.xAxes[0].scaleLabel.labelString = formatTimeAxisStr(sampleRateValue);
		}		
	}
	function graphUpdateYaxesLeftTitle(sampleRateValue){
		graphConfig.options.scales.yAxes[0].scaleLabel.labelString = sampleRateValue;
	}
	
	function formatTitle(speed,distance){
		let out = strBaseTitle;		
		if (speed!=null && distance!= null){
			speed=round(speed,3);
			distance=round(distance,3);
			out += " (V="+String(speed.toFixed(3))+" m/s D="+String(distance.toFixed(3))+" m)";
		}
		return out;
	}
	
	function graphUpdateGraphTitle(titleName){
		graphConfig.options.title.text = titleName;
	}
	
	function channelsEnabler(ch1,ch2){
	
		graphConfig.options.scales.yAxes[0].display = true;
		graphConfig.data.datasets[0].hidden = false;
		
		graphConfig.options.scales.yAxes[1].display = true;
		graphConfig.data.datasets[1].hidden = false;
		
		if(!ch1){
			graphConfig.options.scales.yAxes[0].display = false;
			graphConfig.data.datasets[0].hidden = true;
		}
		
		if(!ch2){
			graphConfig.options.scales.yAxes[1].display = false;
			graphConfig.data.datasets[1].hidden = true;
		}
		myLine.update();
	
	}
	
	Chart.defaults.global.defaultFontSize = 16;
	myLine = new Chart(document.getElementById('graph').getContext('2d'), graphConfig);
	
	
	function reInitChart(){
		firsttimepass = 0;
		setTimeout(function(){
			myLine.destroy();
			myLine = new Chart(document.getElementById('graph').getContext('2d'), graphConfig);
			setTimeout(function(){
				myLine.destroy();
				myLine = new Chart(document.getElementById('graph').getContext('2d'), graphConfig);
			},250);
		},250);
		
	}

	function clearDataset(){
		for( i = 0 ; i < graphConfig.data.datasets.length ; i++ ){
			graphConfig.data.datasets.shift();
		}
		graphConfig.dataSetCounter = 0;
		myLine.update();
	}

	function setGraphLine(){
		if(graphConfig.options.showLines == false){
			graphConfig.options.showLines = true;
			document.getElementById('setLine').childNodes[0].src = "ressource/svg/006-graphique-de-ligne-de-courbe-de-statistiques-commerciales.svg"
		}else if(graphConfig.options.showLines == true){
			graphConfig.options.showLines = false;
			document.getElementById('setLine').childNodes[0].src = "ressource/svg/007-graphique-a-nuage-de-points.svg";
		}
		myLine.update();
	}


ContentForTableur = document.getElementById("tableurContent");

var NewTable;
var DataFeedTab;
var oldTitleX;
var oldTitleY;
function InitTableur(TitleY, TitleX){
	DataFeedTab = 1;
	NewColTable = document.createElement("tr");
	var NewTitleY = document.createElement("td");
	var NewTitleX = document.createElement("td");
	NewTable = document.createElement('table');
	NewTable.id = "table"
	NewTitleX.innerHTML = TitleX;
	NewTitleY.innerHTML = TitleY;
	oldTitleX = TitleX;
	oldTitleY = TitleY;
	ContentForTableur.className = "tabcontent";
	NewTable.className = "tab";
	NewColTable.appendChild(NewTitleX);
	NewColTable.appendChild(NewTitleY);
	NewTable.appendChild(NewColTable);

	
	NewTable.appendChild(NewColTable);
	ContentForTableur.appendChild(NewTable);
	
}
function ReinitTableur(all){
	ContentForTableur.childNodes.forEach(element => {
		ContentForTableur.removeChild(element)
	});
	if(all == null){
		InitTableur(oldTitleY, oldTitleX);
	}else{
		all = null;
	}
}
var FirstPass = true;
function FeedTableur(dataX, dataY){
	
	let NewFeed = document.createElement("tr");
	let FeedX = document.createElement("td");
	let FeedY = document.createElement("td");

	FeedX.id = "dataX" + DataFeedTab;
	FeedY.id = "dataY" + DataFeedTab;

	if(dataX != null){
		FeedX.innerHTML = dataX;
	}else{
		FeedX.innerHTML = (Date.now() - startTimer) /1000;
	}
	FeedY.innerHTML = dataY;

	NewFeed.appendChild(FeedX);
	NewFeed.appendChild(FeedY);

	document.getElementById("table").appendChild(NewFeed);
	DataFeedTab++;
}

function exportcsv(){
	if(document.getElementById("formNewCSV").style.display != "block"){
		document.getElementById("BS_Background").style.display = "block";
		document.getElementById("formNewCSV").style.display = "block";
	}else{
		document.getElementById("BS_Background").style.display = "none";
		document.getElementById("formNewCSV").style.display = "none";
	}


}

function submitFormCSV(){

	if(document.getElementById('NameCSV').value != ""){
		CSVname = document.getElementById('NameCSV').value;
		document.getElementById('formNewCSV').style.display = "none";
		document.getElementById("BS_Background").style.display = "none";

		let compteur = 0;
		let elementtab = []
		var str = "";
			document.getElementById("table").childNodes.forEach(element => {
				element.childNodes.forEach(element2 => {
					str = str.replace(".", ",");
					if(compteur == 2){
						str += "\n";	
						compteur = 0;
					}
					str += element2.textContent;
					
					if(compteur == 1){
					}else{
						
						str += ";";
					}
					compteur++;			
				});
				// str = str.replace(".", ",");	
			});
			str = str.replace(".", ",");
			console.log(str)
			var hiddenElement = document.createElement('a');
			hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(str);
			hiddenElement.target = '_blank';
			hiddenElement.download = CSVname;
			hiddenElement.click();

	}else {
		window.alert("Veuillez remplir le champ vide !")
	}

}
const deleteButtons = document.querySelectorAll('.ResizeBtn');
const deletedPoints = []; 

deleteButtons.forEach(button => {
    button.addEventListener('click', function() {
        const pointIndex = parseInt(document.getElementById('pointToDelete').value, 10);
        deleteGraphPoint(pointIndex - 1); 
        document.getElementById('pointToDelete').value = ''; 
    });
});

function deleteGraphPoint(pointIndex) {
    const dataset = graphConfig.data.datasets[0]; 
    if (dataset.data.length >= pointIndex && pointIndex >= 0) {
        const deletedPoint = dataset.data.splice(pointIndex, 1)[0];
        deletedPoints.push(deletedPoint);
        myLine.update(); 
    }
}


const restoreButton = document.querySelector('.restoreButton');
restoreButton.addEventListener('click', function() {
    restoreDeletedPoint(); 
});


function restoreDeletedPoint() {
    if (deletedPoints.length > 0) {
        const dataset = graphConfig.data.datasets[0]; 
        const lastDeletedPoint = deletedPoints.pop(); 
        dataset.data.push(lastDeletedPoint); 
        myLine.update();
    }
}
const canvas = document.getElementById('graph');
let currentPopup = null;

canvas.addEventListener('mousemove', function (event) {
    const activePoints = myLine.getElementsAtEventForMode(event, 'nearest', { intersect: true }, false);

    if (activePoints.length > 0) {
        const idx = activePoints[0]._index + 1; 

        
        const mouseX = event.clientX;
        const mouseY = event.clientY;

       
            
		currentPopup.textContent = `Point: ${idx}`;
		currentPopup.style.top = `${mouseY + 20}px`;
		currentPopup.style.left = `${mouseX + 20}px`;
        
    } else if (currentPopup) {
       
        currentPopup.remove();
        currentPopup = null;
    }
});
  function enregistrerFichiers() {
          
            console.log("Enregistrement des fichiers .blk et .py");
        }

        // Attacher l'événement beforeunload à la fenêtre
        window.addEventListener('beforeunload', function (event) {
           
            enregistrerFichiers();
            
            
            var message = "Des modifications non enregistrées peuvent être perdues. Êtes-vous sûr de vouloir quitter?";
            event.returnValue = message; // Standard
            return message; // Pour certains navigateurs anciens
        });
		
function enregistrerFichiersAvantFermeture() {
    if (stateconnected === true) {
        let strFilePartPy = btoa(editor.getValue());

        var xml = Blockly.Xml.workspaceToDom(workspace);
        var xml_text = Blockly.Xml.domToText(xml);

        
        if (!xml_text.trim()) {
            xml_text = '';
        }

        let strFilePartBlk = btoa(xml_text);

        // Utiliser le chemin actuel pour les noms de fichier
        var nomFichierSansExtension = currenFilePath.substr(1) + currenFilePath.substr(currenFilePath.lastIndexOf("/"));
        
        // Créer les commandes pour enregistrer les fichiers
        var cmd = "";
        cmd += "file = open(\"" + nomFichierSansExtension + ".py\",'w')" + "\r\n";
        cmd += "file.write('" + strFilePartPy + "')" + "\r\n";
        cmd += "file.close()" + "\r\n";
        cmd += "file = open(\"" + nomFichierSansExtension + ".blk\",'w')" + "\r\n";
        cmd += "file.write(\"" + strFilePartBlk + "\")" + "\r\n";
        cmd += "file.close()" + "\r\n";

        // Exécuter les commandes dans le contexte MicroPython
        if (!ppy.isInRAWReplMode()) {
            ppy.enterRawRepl().then(function (res) {
                ppy.exec(cmd).then(function (res) {
                    
                });
            });
        } else {
            ppy.exec(cmd).then(function (res) {
                
            });
        }
    } else {
        connectionPPY();
    }
}
window.addEventListener('beforeunload', function (event) {
    enregistrerFichiersAvantFermeture();
    
    var message = "Des modifications non enregistrées peuvent être perdues. Êtes-vous sûr de vouloir quitter?";
    
    // Utilisez la propriété `returnValue` de l'événement
    event.returnValue = message;

    // Pour une compatibilité avec les navigateurs anciens
    return message;
});

var autoriserEdition = true;

// Fonction pour bloquer la saisie dans l'éditeur
function bloquerSaisie(event) {
    // Annuler l'événement d'entrée (saisie de texte)
    event.preventDefault();
}

// Fonction pour afficher une popup d'avertissement lors du clic sur l'espace de l'éditeur
function afficherPopupAvertissement(event) {
    console.log("Clic détecté sur l'éditeur");

    if (autoriserEdition) {
        var confirmer = window.confirm("Attention : Veuillez tirer le bloc <Code> présent dans l'éditeur.");

        if (!confirmer) {
            // Désactiver l'édition après confirmation
            console.log("Édition désactivée après confirmation");
            autoriserEdition = false;
            editorElement.removeAttribute('contenteditable');
            editorElement.removeEventListener('input', bloquerSaisie);
        } else {
            // Annuler l'événement de clic si l'utilisateur a cliqué sur "Annuler" dans la popup
            console.log("Événement de clic annulé après annulation de la confirmation");
            event.preventDefault();
        }
    }
}

var editorElement = document.getElementById('editor');

if (editorElement) {
    editorElement.addEventListener('click', afficherPopupAvertissement);
    editorElement.addEventListener('input', bloquerSaisie);
}
