|  | @ -117,6 +117,7 @@ static const char management_HTML[] PROGMEM = "<!DOCTYPE html>\ | 
		
	
		
			
				|  |  |     <nav>\ |  |  |     <nav>\ | 
		
	
		
			
				|  |  |         <div class=\"container nav nav-tabs\" id=\"nav-tab\" role=\"tablist\">\ |  |  |         <div class=\"container nav nav-tabs\" id=\"nav-tab\" role=\"tablist\">\ | 
		
	
		
			
				|  |  |             <a class=\"nav-item nav-link active\" id=\"nav-rfid-tab\" data-toggle=\"tab\" href=\"#nav-rfid\" role=\"tab\" aria-controls=\"nav-rfid\" aria-selected=\"true\"><i class=\"fas fa-dot-circle\"></i> RFID</a>\ |  |  |             <a class=\"nav-item nav-link active\" id=\"nav-rfid-tab\" data-toggle=\"tab\" href=\"#nav-rfid\" role=\"tab\" aria-controls=\"nav-rfid\" aria-selected=\"true\"><i class=\"fas fa-dot-circle\"></i> RFID</a>\ | 
		
	
		
			
				|  |  |  |  |  |             <a class=\"nav-item nav-link\" id=\"nav-files-tab\" data-toggle=\"tab\" href=\"#nav-files\" role=\"tab\" aria-controls=\"nav-files\" aria-selected=\"false\"><i class=\"fas fa-folder\"></i> Dateien</a>\ | 
		
	
		
			
				|  |  |             <a class=\"nav-item nav-link\" id=\"nav-wifi-tab\" data-toggle=\"tab\" href=\"#nav-wifi\" role=\"tab\" aria-controls=\"nav-wifi\" aria-selected=\"false\"><i class=\"fas fa-wifi\"></i><span class=\".d-sm-none .d-md-block\"> WLAN</span></a>\ |  |  |             <a class=\"nav-item nav-link\" id=\"nav-wifi-tab\" data-toggle=\"tab\" href=\"#nav-wifi\" role=\"tab\" aria-controls=\"nav-wifi\" aria-selected=\"false\"><i class=\"fas fa-wifi\"></i><span class=\".d-sm-none .d-md-block\"> WLAN</span></a>\ | 
		
	
		
			
				|  |  |             %SHOW_MQTT_TAB%\ |  |  |             %SHOW_MQTT_TAB%\ | 
		
	
		
			
				|  |  |             %SHOW_FTP_TAB%\ |  |  |             %SHOW_FTP_TAB%\ | 
		
	
	
		
			
				|  | @ -126,6 +127,21 @@ static const char management_HTML[] PROGMEM = "<!DOCTYPE html>\ | 
		
	
		
			
				|  |  |     </nav>\ |  |  |     </nav>\ | 
		
	
		
			
				|  |  | <br>\ |  |  | <br>\ | 
		
	
		
			
				|  |  | <div class=\"tab-content\" id=\"nav-tabContent\">\ |  |  | <div class=\"tab-content\" id=\"nav-tabContent\">\ | 
		
	
		
			
				|  |  |  |  |  |     <div class=\"tab-pane fade\" id=\"nav-files\" role=\"tabpanel\" aria-labelledby=\"nav-files-tab\">\ | 
		
	
		
			
				|  |  |  |  |  |         <div class=\"container\" id=\"fileExplorer\">\ | 
		
	
		
			
				|  |  |  |  |  |             <div class=\"ui-widget\">\ | 
		
	
		
			
				|  |  |  |  |  |                 <div class=\"filetree demo\" id=\"explorerTree\"></div>\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  |                 <form id=\"explorerUploadForm\" method=\"POST\" enctype=\"multipart/form-data\" action=\"/explorer\" accept-charset=\"iso-8859-1\">\ | 
		
	
		
			
				|  |  |  |  |  |                     <input id=\"explorerUploadedFiles\" type=\"file\" class=\"form-control-file\" name=\"explorerUploadFiles\" multiple> <input type=\"submit\" class=\"btn btn-primary\" id=\"submit\" value=\"Hochladen\">\ | 
		
	
		
			
				|  |  |  |  |  |                 </form>\ | 
		
	
		
			
				|  |  |  |  |  |                 <div>\ | 
		
	
		
			
				|  |  |  |  |  |                     <progress id=\"explorerUploadProgress\" style=\"margin-top:10px\" value=\"0\" max=\"100\"></progress> <span id=\"explorerUploadPercent\"></span>\ | 
		
	
		
			
				|  |  |  |  |  |                 </div>\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  |             </div>\ | 
		
	
		
			
				|  |  |  |  |  |         </div>\ | 
		
	
		
			
				|  |  |  |  |  |     </div>\ | 
		
	
		
			
				|  |  |     <div class=\"tab-pane fade\" id=\"nav-wifi\" role=\"tabpanel\" aria-labelledby=\"nav-wifi-tab\">\ |  |  |     <div class=\"tab-pane fade\" id=\"nav-wifi\" role=\"tabpanel\" aria-labelledby=\"nav-wifi-tab\">\ | 
		
	
		
			
				|  |  |         <div class=\"container\" id=\"wifiConfig\">\ |  |  |         <div class=\"container\" id=\"wifiConfig\">\ | 
		
	
		
			
				|  |  |             <form action=\"#wifiConfig\" method=\"POST\" onsubmit=\"wifiConfig('wifiConfig'); return false\">\ |  |  |             <form action=\"#wifiConfig\" method=\"POST\" onsubmit=\"wifiConfig('wifiConfig'); return false\">\ | 
		
	
	
		
			
				|  | @ -443,6 +459,399 @@ static const char management_HTML[] PROGMEM = "<!DOCTYPE html>\ | 
		
	
		
			
				|  |  |         });\ |  |  |         });\ | 
		
	
		
			
				|  |  |     }\ |  |  |     }\ | 
		
	
		
			
				|  |  | \ |  |  | \ | 
		
	
		
			
				|  |  |  |  |  |     /* File Explorer functions begin*/\ | 
		
	
		
			
				|  |  |  |  |  |     var lastSelectedNodePath = \"\";\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  |     $('#explorerTree').on('select_node.jstree', function (e, data) {\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  |         $('input[name=fileOrUrl]').val(data.node.data.path);\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  |         if (data.node.type == \"folder\") {\ | 
		
	
		
			
				|  |  |  |  |  |             $('.option-folder').show();\ | 
		
	
		
			
				|  |  |  |  |  |             $('.option-file').hide();\ | 
		
	
		
			
				|  |  |  |  |  |             $('#playMode option').removeAttr('selected').filter('[value=3]').attr('selected', true);\ | 
		
	
		
			
				|  |  |  |  |  |         }\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  |         if (data.node.type == \"audio\") {\ | 
		
	
		
			
				|  |  |  |  |  |             $('.option-file').show();\ | 
		
	
		
			
				|  |  |  |  |  |             $('.option-folder').hide();\ | 
		
	
		
			
				|  |  |  |  |  |             $('#playMode option').removeAttr('selected').filter('[value=1]').attr('selected', true);\ | 
		
	
		
			
				|  |  |  |  |  |         }\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  |         if(lastSelectedNodePath != data.node.data.path) {\ | 
		
	
		
			
				|  |  |  |  |  |             if (data.node.data.directory) {\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  |                 var ref = $('#explorerTree').jstree(true),\ | 
		
	
		
			
				|  |  |  |  |  |                     sel = ref.get_selected();\ | 
		
	
		
			
				|  |  |  |  |  |                 if(!sel.length) { return false; }\ | 
		
	
		
			
				|  |  |  |  |  |                 sel = sel[0];\ | 
		
	
		
			
				|  |  |  |  |  |                 var children = $(\"#explorerTree\").jstree(\"get_children_dom\",sel);\ | 
		
	
		
			
				|  |  |  |  |  |                 /* refresh only, when there is no child -> possible not yet updated */\ | 
		
	
		
			
				|  |  |  |  |  |                 if(children.length < 1){\ | 
		
	
		
			
				|  |  |  |  |  |                     refreshNode(sel);\ | 
		
	
		
			
				|  |  |  |  |  |                 }\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  |             }\ | 
		
	
		
			
				|  |  |  |  |  |          lastSelectedNodePath = data.node.data.path;\ | 
		
	
		
			
				|  |  |  |  |  |         }\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  |     });\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	function doRest(path, callback, obj) {\ | 
		
	
		
			
				|  |  |  |  |  | 		obj.url      = path;\ | 
		
	
		
			
				|  |  |  |  |  | 		obj.dataType = \"json\";\ | 
		
	
		
			
				|  |  |  |  |  | 		obj.contentType= \"application/json;charset=iso-8859-1\",\ | 
		
	
		
			
				|  |  |  |  |  | 		obj.scriptCharset= \"iso-8859-1\",\ | 
		
	
		
			
				|  |  |  |  |  | 		obj.success  = function(data, textStatus, jqXHR) {\ | 
		
	
		
			
				|  |  |  |  |  | 			if (callback) {\ | 
		
	
		
			
				|  |  |  |  |  | 				callback(data);\ | 
		
	
		
			
				|  |  |  |  |  | 			}\ | 
		
	
		
			
				|  |  |  |  |  | 		};\ | 
		
	
		
			
				|  |  |  |  |  | 		obj.error    = function(jqXHR, textStatus, errorThrown) {\ | 
		
	
		
			
				|  |  |  |  |  | 			console.log(\"AJAX error\");\ | 
		
	
		
			
				|  |  |  |  |  | 			/*debugger; */\ | 
		
	
		
			
				|  |  |  |  |  | 		};\ | 
		
	
		
			
				|  |  |  |  |  | 		jQuery.ajax(obj);\ | 
		
	
		
			
				|  |  |  |  |  | 	} /* doRest */\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	function getData(path, callback) {\ | 
		
	
		
			
				|  |  |  |  |  | 		doRest(path, callback, {\ | 
		
	
		
			
				|  |  |  |  |  | 			method   : \"GET\"\ | 
		
	
		
			
				|  |  |  |  |  | 		});\ | 
		
	
		
			
				|  |  |  |  |  | 	} /* getData */\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	function deleteData(path, callback, _data) {\ | 
		
	
		
			
				|  |  |  |  |  | 		doRest(path, callback, {\ | 
		
	
		
			
				|  |  |  |  |  | 			method   : \"DELETE\",\ | 
		
	
		
			
				|  |  |  |  |  | 			data: _data\ | 
		
	
		
			
				|  |  |  |  |  | 		});\ | 
		
	
		
			
				|  |  |  |  |  | 	} /* deleteData */\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	function patchData(path, callback, _data) {\ | 
		
	
		
			
				|  |  |  |  |  | 		doRest(path, callback, {\ | 
		
	
		
			
				|  |  |  |  |  | 			method   : \"PATCH\",\ | 
		
	
		
			
				|  |  |  |  |  | 			data: _data\ | 
		
	
		
			
				|  |  |  |  |  | 		});\ | 
		
	
		
			
				|  |  |  |  |  | 	} /* patchData */\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	function postData(path, callback, _data) {\ | 
		
	
		
			
				|  |  |  |  |  | 		doRest(path, callback, {\ | 
		
	
		
			
				|  |  |  |  |  | 			method   : \"POST\",\ | 
		
	
		
			
				|  |  |  |  |  | 			data: _data\ | 
		
	
		
			
				|  |  |  |  |  | 		});\ | 
		
	
		
			
				|  |  |  |  |  | 	} /* postData */\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	function putData(path, callback, _data) {\ | 
		
	
		
			
				|  |  |  |  |  | 		doRest(path, callback, {\ | 
		
	
		
			
				|  |  |  |  |  | 			method   : \"PUT\",\ | 
		
	
		
			
				|  |  |  |  |  | 			data: _data\ | 
		
	
		
			
				|  |  |  |  |  | 		});\ | 
		
	
		
			
				|  |  |  |  |  | 	} /* putData */\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	/* File Upload */\ | 
		
	
		
			
				|  |  |  |  |  | 	$('#explorerUploadForm').submit(function(e){\ | 
		
	
		
			
				|  |  |  |  |  | 		e.preventDefault();\ | 
		
	
		
			
				|  |  |  |  |  | 		console.log(\"Upload!\");\ | 
		
	
		
			
				|  |  |  |  |  | 		var data = new FormData(this);\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 		var ref = $('#explorerTree').jstree(true),\ | 
		
	
		
			
				|  |  |  |  |  | 			sel = ref.get_selected(),\ | 
		
	
		
			
				|  |  |  |  |  | 			path = \"/\";\ | 
		
	
		
			
				|  |  |  |  |  | 		if(!sel.length) { alert(\"Please select the upload location!\");return false; }\ | 
		
	
		
			
				|  |  |  |  |  | 		sel = sel[0];\ | 
		
	
		
			
				|  |  |  |  |  | 		selectedNode = ref.get_node(sel);\ | 
		
	
		
			
				|  |  |  |  |  | 		if(selectedNode.data.directory){\ | 
		
	
		
			
				|  |  |  |  |  | 			path = selectedNode.data.path\ | 
		
	
		
			
				|  |  |  |  |  | 		} else {\ | 
		
	
		
			
				|  |  |  |  |  | 			/* remap sel to parent folder */\ | 
		
	
		
			
				|  |  |  |  |  | 			sel = ref.get_node(ref.get_parent(sel));\ | 
		
	
		
			
				|  |  |  |  |  | 			path = parentNode.data.path;\ | 
		
	
		
			
				|  |  |  |  |  | 			console.log(\"Parent path: \" + path);\ | 
		
	
		
			
				|  |  |  |  |  | 		}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 		$.ajax({\ | 
		
	
		
			
				|  |  |  |  |  | 			url: '/explorer?path=' + path,\ | 
		
	
		
			
				|  |  |  |  |  |             type: 'POST',\ | 
		
	
		
			
				|  |  |  |  |  |             data: data,\ | 
		
	
		
			
				|  |  |  |  |  |             contentType: false,\ | 
		
	
		
			
				|  |  |  |  |  |             processData:false,\ | 
		
	
		
			
				|  |  |  |  |  | 			xhr: function() {\ | 
		
	
		
			
				|  |  |  |  |  | 				var xhr = new window.XMLHttpRequest();\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 				xhr.upload.addEventListener(\"progress\", function(evt) {\ | 
		
	
		
			
				|  |  |  |  |  | 				  if (evt.lengthComputable) {\ | 
		
	
		
			
				|  |  |  |  |  | 					var percentComplete = evt.loaded / evt.total;\ | 
		
	
		
			
				|  |  |  |  |  | 					percentComplete = parseInt(percentComplete * 100);\ | 
		
	
		
			
				|  |  |  |  |  | 					console.log(percentComplete);\ | 
		
	
		
			
				|  |  |  |  |  | 					document.getElementById(\"explorerUploadProgress\").value = percentComplete;\ | 
		
	
		
			
				|  |  |  |  |  | 					document.getElementById(\"explorerUploadPercent\").innerHTML = percentComplete + \"%\";\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 					if (percentComplete === 100) {\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 					}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  |                     Sleep(1000);\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 				  }\ | 
		
	
		
			
				|  |  |  |  |  | 				}, false);\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 				return xhr;\ | 
		
	
		
			
				|  |  |  |  |  | 			},\ | 
		
	
		
			
				|  |  |  |  |  | 			success: function(data, textStatus, jqXHR) {\ | 
		
	
		
			
				|  |  |  |  |  | 				console.log(\"Upload success!\");\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 				getData(\"/explorer?path=\" + path, function(data) {\ | 
		
	
		
			
				|  |  |  |  |  | 					/* We now have data! */\ | 
		
	
		
			
				|  |  |  |  |  | 					deleteChildrenNodes(sel);\ | 
		
	
		
			
				|  |  |  |  |  | 					addFileDirectory(sel, data);\ | 
		
	
		
			
				|  |  |  |  |  | 					ref.open_node(sel);\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 				});\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 			}\ | 
		
	
		
			
				|  |  |  |  |  |         });\ | 
		
	
		
			
				|  |  |  |  |  | 	});\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	/* File Delete */\ | 
		
	
		
			
				|  |  |  |  |  | 	function handleDeleteData(nodeId) {\ | 
		
	
		
			
				|  |  |  |  |  | 		var ref = $('#explorerTree').jstree(true);\ | 
		
	
		
			
				|  |  |  |  |  | 		var node = ref.get_node(nodeId);\ | 
		
	
		
			
				|  |  |  |  |  | 		var children = $(\"#explorerTree\").jstree(\"get_children_dom\",nodeId);\ | 
		
	
		
			
				|  |  |  |  |  | 		console.log(children.length);\ | 
		
	
		
			
				|  |  |  |  |  | 		if(node.data.directory) {\ | 
		
	
		
			
				|  |  |  |  |  | 			if(children.length > 0) {\ | 
		
	
		
			
				|  |  |  |  |  | 				for(var i=0;i<children.length;i++)\ | 
		
	
		
			
				|  |  |  |  |  | 				{\ | 
		
	
		
			
				|  |  |  |  |  | 					console.log(\"call delete function for: \" + children[i].text);\ | 
		
	
		
			
				|  |  |  |  |  | 					handleDeleteData(children[i].id);\ | 
		
	
		
			
				|  |  |  |  |  | 				}\ | 
		
	
		
			
				|  |  |  |  |  | 			}\ | 
		
	
		
			
				|  |  |  |  |  | 		}\ | 
		
	
		
			
				|  |  |  |  |  | 		console.log(\"call delete request: \" + node.data.path);\ | 
		
	
		
			
				|  |  |  |  |  | 		deleteData(\"/explorer?path=\" + node.data.path);\ | 
		
	
		
			
				|  |  |  |  |  | 	}\ | 
		
	
		
			
				|  |  |  |  |  |     function Sleep(milliseconds) {\ | 
		
	
		
			
				|  |  |  |  |  |      return new Promise(resolve => setTimeout(resolve, milliseconds));\ | 
		
	
		
			
				|  |  |  |  |  |     }\ | 
		
	
		
			
				|  |  |  |  |  | 	function fileNameSort( a, b ) {\ | 
		
	
		
			
				|  |  |  |  |  | 		if ( a.dir && !b.dir ) {\ | 
		
	
		
			
				|  |  |  |  |  | 			return -1\ | 
		
	
		
			
				|  |  |  |  |  | 		}\ | 
		
	
		
			
				|  |  |  |  |  | 		if ( !a.dir && b.dir ) {\ | 
		
	
		
			
				|  |  |  |  |  | 			return 1\ | 
		
	
		
			
				|  |  |  |  |  | 		}\ | 
		
	
		
			
				|  |  |  |  |  | 		if ( a.name < b.name ){\ | 
		
	
		
			
				|  |  |  |  |  | 			return -1;\ | 
		
	
		
			
				|  |  |  |  |  | 		}\ | 
		
	
		
			
				|  |  |  |  |  | 		if ( a.name > b.name ){\ | 
		
	
		
			
				|  |  |  |  |  | 			return 1;\ | 
		
	
		
			
				|  |  |  |  |  | 		}\ | 
		
	
		
			
				|  |  |  |  |  | 		return 0;\ | 
		
	
		
			
				|  |  |  |  |  | 	}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	function createChild(nodeId, data) {\ | 
		
	
		
			
				|  |  |  |  |  | 		var ref = $('#explorerTree').jstree(true);\ | 
		
	
		
			
				|  |  |  |  |  | 		var node = ref.get_node(nodeId);\ | 
		
	
		
			
				|  |  |  |  |  | 		var child = {\ | 
		
	
		
			
				|  |  |  |  |  | 			text: data.name,\ | 
		
	
		
			
				|  |  |  |  |  | 			type: getType(data),\ | 
		
	
		
			
				|  |  |  |  |  | 			data: {\ | 
		
	
		
			
				|  |  |  |  |  | 				path: node.data.path + \"/\" + data.name,\ | 
		
	
		
			
				|  |  |  |  |  | 				directory: data.dir\ | 
		
	
		
			
				|  |  |  |  |  | 			}\ | 
		
	
		
			
				|  |  |  |  |  | 		}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 		return child;\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	function deleteChildrenNodes(nodeId) {\ | 
		
	
		
			
				|  |  |  |  |  | 		var ref = $('#explorerTree').jstree(true);\ | 
		
	
		
			
				|  |  |  |  |  | 		var children = $(\"#explorerTree\").jstree(\"get_children_dom\",nodeId);\ | 
		
	
		
			
				|  |  |  |  |  | 		for(var i=0;i<children.length;i++)\ | 
		
	
		
			
				|  |  |  |  |  | 		{\ | 
		
	
		
			
				|  |  |  |  |  | 			ref.delete_node(children[i].id);\ | 
		
	
		
			
				|  |  |  |  |  | 		}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	function refreshNode(nodeId) {\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 		var ref = $('#explorerTree').jstree(true);\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 		var node = ref.get_node(nodeId);\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 		getData(\"/explorer?path=\" + node.data.path, function(data) {\ | 
		
	
		
			
				|  |  |  |  |  | 			/* We now have data! */\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 			deleteChildrenNodes(nodeId);\ | 
		
	
		
			
				|  |  |  |  |  | 			addFileDirectory(nodeId, data);\ | 
		
	
		
			
				|  |  |  |  |  | 			ref.open_node(nodeId);\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 		});\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	function getType(data) {\ | 
		
	
		
			
				|  |  |  |  |  | 		var type = \"\";\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 		if(data.dir) {\ | 
		
	
		
			
				|  |  |  |  |  | 			type = \"folder\";\ | 
		
	
		
			
				|  |  |  |  |  | 		} else if ((/\\.(mp3|MP3|ogg|wav|WAV|OGG|wma|WMA|acc|ACC|flac|FLAC)$/i).test(data.name)) {\ | 
		
	
		
			
				|  |  |  |  |  | 			type = \"audio\";\ | 
		
	
		
			
				|  |  |  |  |  | 		} else {\ | 
		
	
		
			
				|  |  |  |  |  | 			type = \"file\";\ | 
		
	
		
			
				|  |  |  |  |  | 		}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 		return type;\ | 
		
	
		
			
				|  |  |  |  |  | 	}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	function addFileDirectory(parent, data) {\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 		data.sort( fileNameSort );\ | 
		
	
		
			
				|  |  |  |  |  | 		var ref = $('#explorerTree').jstree(true);\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 		for (var i=0; i<data.length; i++) {\ | 
		
	
		
			
				|  |  |  |  |  | 			console.log(\"Create Node\");\ | 
		
	
		
			
				|  |  |  |  |  | 			ref.create_node(parent, createChild(parent, data[i]));\ | 
		
	
		
			
				|  |  |  |  |  | 		}\ | 
		
	
		
			
				|  |  |  |  |  | 	} /* addFileDirectory */\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 	function buildFileSystemTree(path) {\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 		$('#explorerTree').jstree({\ | 
		
	
		
			
				|  |  |  |  |  | 				\"core\" : {\ | 
		
	
		
			
				|  |  |  |  |  | 						\"check_callback\" : true,\ | 
		
	
		
			
				|  |  |  |  |  | 						'force_text' : true,\ | 
		
	
		
			
				|  |  |  |  |  | 						\"themes\" : { \"stripes\" : true },\ | 
		
	
		
			
				|  |  |  |  |  | 						'data' : {	text: '/',\ | 
		
	
		
			
				|  |  |  |  |  | 									state: {\ | 
		
	
		
			
				|  |  |  |  |  | 										opened: true\ | 
		
	
		
			
				|  |  |  |  |  | 									},\ | 
		
	
		
			
				|  |  |  |  |  | 									type: 'folder',\ | 
		
	
		
			
				|  |  |  |  |  | 									children: [],\ | 
		
	
		
			
				|  |  |  |  |  | 									data: {\ | 
		
	
		
			
				|  |  |  |  |  | 										path: '/',\ | 
		
	
		
			
				|  |  |  |  |  | 										directory: true\ | 
		
	
		
			
				|  |  |  |  |  | 								}}\ | 
		
	
		
			
				|  |  |  |  |  | 					},\ | 
		
	
		
			
				|  |  |  |  |  | 					'types': {\ | 
		
	
		
			
				|  |  |  |  |  | 						'folder': {\ | 
		
	
		
			
				|  |  |  |  |  | 							'icon': \"fa fa-folder\"\ | 
		
	
		
			
				|  |  |  |  |  | 						},\ | 
		
	
		
			
				|  |  |  |  |  | 						'file': {\ | 
		
	
		
			
				|  |  |  |  |  | 							'icon': \"fa fa-file\"\ | 
		
	
		
			
				|  |  |  |  |  | 						},\ | 
		
	
		
			
				|  |  |  |  |  | 						'audio': {\ | 
		
	
		
			
				|  |  |  |  |  | 							'icon': \"fa fa-file-audio\"\ | 
		
	
		
			
				|  |  |  |  |  | 						},\ | 
		
	
		
			
				|  |  |  |  |  | 						'default': {\ | 
		
	
		
			
				|  |  |  |  |  | 							'icon': \"fa fa-folder\"\ | 
		
	
		
			
				|  |  |  |  |  | 						}\ | 
		
	
		
			
				|  |  |  |  |  | 					},\ | 
		
	
		
			
				|  |  |  |  |  | 				plugins: [\"contextmenu\", \"themes\", \"types\"],\ | 
		
	
		
			
				|  |  |  |  |  | 				contextmenu: {\ | 
		
	
		
			
				|  |  |  |  |  | 					items: function(nodeId) {\ | 
		
	
		
			
				|  |  |  |  |  | 						var ref = $('#explorerTree').jstree(true);\ | 
		
	
		
			
				|  |  |  |  |  | 						var node = ref.get_node(nodeId);\ | 
		
	
		
			
				|  |  |  |  |  | 						var items = {};\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 						if (node.data.directory) {\ | 
		
	
		
			
				|  |  |  |  |  | 							items.createDir = {\ | 
		
	
		
			
				|  |  |  |  |  | 							label: \"Neuer Ordner\",\ | 
		
	
		
			
				|  |  |  |  |  | 							action: function(x) {\ | 
		
	
		
			
				|  |  |  |  |  | 								var childNode = ref.create_node(nodeId, {text: \"Neuer Ordner\", type: \"folder\"});\ | 
		
	
		
			
				|  |  |  |  |  | 								if(childNode) {\ | 
		
	
		
			
				|  |  |  |  |  | 									ref.edit(childNode, null, function(childNode, status){\ | 
		
	
		
			
				|  |  |  |  |  | 										putData(\"/explorer?path=\" + node.data.path + \"/\" + childNode.text);\ | 
		
	
		
			
				|  |  |  |  |  | 										refreshNode(nodeId);\ | 
		
	
		
			
				|  |  |  |  |  | 									});\ | 
		
	
		
			
				|  |  |  |  |  | 								}\ | 
		
	
		
			
				|  |  |  |  |  | 							}\ | 
		
	
		
			
				|  |  |  |  |  | 						}\ | 
		
	
		
			
				|  |  |  |  |  | 						}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 						/* Play */\ | 
		
	
		
			
				|  |  |  |  |  | 						items.play = {\ | 
		
	
		
			
				|  |  |  |  |  | 							label: \"Abspielen\",\ | 
		
	
		
			
				|  |  |  |  |  | 							action: function(x) {\ | 
		
	
		
			
				|  |  |  |  |  | 								var playMode = node.data.directory?\"5\":\"1\";\ | 
		
	
		
			
				|  |  |  |  |  | 								postData(\"/exploreraudio?path=\" + node.data.path + \"&playmode=\" + playMode);\ | 
		
	
		
			
				|  |  |  |  |  | 							}\ | 
		
	
		
			
				|  |  |  |  |  | 						}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 						/* Refresh */\ | 
		
	
		
			
				|  |  |  |  |  | 						items.refresh = {\ | 
		
	
		
			
				|  |  |  |  |  | 							label: \"Aktualisieren\",\ | 
		
	
		
			
				|  |  |  |  |  | 							action: function(x) {\ | 
		
	
		
			
				|  |  |  |  |  | 								refreshNode(nodeId);\ | 
		
	
		
			
				|  |  |  |  |  | 							}\ | 
		
	
		
			
				|  |  |  |  |  | 						}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 						/* Delete */\ | 
		
	
		
			
				|  |  |  |  |  | 						items.delete = {\ | 
		
	
		
			
				|  |  |  |  |  | 							label: \"Loeschen\",\ | 
		
	
		
			
				|  |  |  |  |  | 							action: function(x) {\ | 
		
	
		
			
				|  |  |  |  |  | 								handleDeleteData(nodeId);\ | 
		
	
		
			
				|  |  |  |  |  | 								refreshNode(ref.get_parent(nodeId));\ | 
		
	
		
			
				|  |  |  |  |  | 							}\ | 
		
	
		
			
				|  |  |  |  |  | 						}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 						/* Rename */\ | 
		
	
		
			
				|  |  |  |  |  | 						items.rename = {\ | 
		
	
		
			
				|  |  |  |  |  | 							label: \"Umbenennen\",\ | 
		
	
		
			
				|  |  |  |  |  | 							action: function(x) {\ | 
		
	
		
			
				|  |  |  |  |  | 								var srcPath = node.data.path;\ | 
		
	
		
			
				|  |  |  |  |  | 								ref.edit(nodeId, null, function(node, status){\ | 
		
	
		
			
				|  |  |  |  |  | 									node.data.path = node.data.path.substring(0,node.data.path.lastIndexOf(\"/\")+1) + node.text;\ | 
		
	
		
			
				|  |  |  |  |  | 									patchData(\"/explorer?srcpath=\" + srcPath + \"&dstpath=\" + node.data.path);\ | 
		
	
		
			
				|  |  |  |  |  | 									refreshNode(ref.get_parent(nodeId));\ | 
		
	
		
			
				|  |  |  |  |  | 								});\ | 
		
	
		
			
				|  |  |  |  |  | 							}\ | 
		
	
		
			
				|  |  |  |  |  | 						}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 					   return items;\ | 
		
	
		
			
				|  |  |  |  |  | 					}\ | 
		
	
		
			
				|  |  |  |  |  | 				}\ | 
		
	
		
			
				|  |  |  |  |  | 			});\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 		if (path.length == 0) {\ | 
		
	
		
			
				|  |  |  |  |  | 			return;\ | 
		
	
		
			
				|  |  |  |  |  | 		}\ | 
		
	
		
			
				|  |  |  |  |  | 		getData(\"/explorer?path=/\", function(data) {\ | 
		
	
		
			
				|  |  |  |  |  | 			/* We now have data! */\ | 
		
	
		
			
				|  |  |  |  |  | 			$('#explorerTree').jstree(true).settings.core.data.children = [];\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 			data.sort( fileNameSort );\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 			for (var i=0; i<data.length; i++) {\ | 
		
	
		
			
				|  |  |  |  |  | 				var newChild = {\ | 
		
	
		
			
				|  |  |  |  |  | 					text: data[i].name,\ | 
		
	
		
			
				|  |  |  |  |  | 					type: getType(data[i]),\ | 
		
	
		
			
				|  |  |  |  |  | 					data: {\ | 
		
	
		
			
				|  |  |  |  |  | 						path: \"/\" + data[i].name,\ | 
		
	
		
			
				|  |  |  |  |  | 						directory: data[i].dir\ | 
		
	
		
			
				|  |  |  |  |  | 					},\ | 
		
	
		
			
				|  |  |  |  |  | 					children: []\ | 
		
	
		
			
				|  |  |  |  |  | 				}\ | 
		
	
		
			
				|  |  |  |  |  | 				$('#explorerTree').jstree(true).settings.core.data.children.push(newChild);\ | 
		
	
		
			
				|  |  |  |  |  | 			}\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 			$(\"#explorerTree\").jstree(true).refresh();\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  | 		});\ | 
		
	
		
			
				|  |  |  |  |  | 	} /* buildFileSystemTree */\ | 
		
	
		
			
				|  |  |  |  |  | \ | 
		
	
		
			
				|  |  |  |  |  |     /* File Explorer functions end */\ | 
		
	
		
			
				|  |  |     function renderFileTree() {\ |  |  |     function renderFileTree() {\ | 
		
	
		
			
				|  |  | \ |  |  | \ | 
		
	
		
			
				|  |  |         var filesURI = \"/files\";\ |  |  |         var filesURI = \"/files\";\ | 
		
	
	
		
			
				|  | @ -715,6 +1124,7 @@ static const char management_HTML[] PROGMEM = "<!DOCTYPE html>\ | 
		
	
		
			
				|  |  |     $(document).ready(function () {\ |  |  |     $(document).ready(function () {\ | 
		
	
		
			
				|  |  |         connect();\ |  |  |         connect();\ | 
		
	
		
			
				|  |  |         renderFileTree();\ |  |  |         renderFileTree();\ | 
		
	
		
			
				|  |  |  |  |  | 		buildFileSystemTree(\"/\");\ | 
		
	
		
			
				|  |  | \ |  |  | \ | 
		
	
		
			
				|  |  |         console.log(parseInt(document.getElementById('warningLowVoltage').value));\ |  |  |         console.log(parseInt(document.getElementById('warningLowVoltage').value));\ | 
		
	
		
			
				|  |  |         $(function () {\ |  |  |         $(function () {\ | 
		
	
	
		
			
				|  | 
 |