From 63288601e7e359cd4899f5ec6b040ff4e4f234c4 Mon Sep 17 00:00:00 2001
From: marsman7
Date: Sat, 20 Apr 2024 16:13:32 +0200
Subject: [PATCH 001/142] add crowpanel hmi 5inch 800x480
---
user_setups/esp32s3/crowpanel-hmi.ini | 82 +++++++++++++++++++++++++--
1 file changed, 77 insertions(+), 5 deletions(-)
diff --git a/user_setups/esp32s3/crowpanel-hmi.ini b/user_setups/esp32s3/crowpanel-hmi.ini
index 86d5fc17..5a6be7c0 100644
--- a/user_setups/esp32s3/crowpanel-hmi.ini
+++ b/user_setups/esp32s3/crowpanel-hmi.ini
@@ -1,5 +1,5 @@
;***************************************************;
-; Elecrow ESP32-S3 TFT 7.0" ;
+; Elecrow ESP32-S3 HMI TFT 7.0" and 5.0" ;
; - Custom esp32-s3 board ;
; - gt911 touch controller ;
;***************************************************;
@@ -81,11 +81,9 @@ extends = elecrow-esp32-s3-tft, flash_4mb
build_flags =
-D HASP_MODEL="Elecrow WZ8048C070"
- -D HASP_LOG_LEVEL=LOG_LEVEL_VERBOSE
+ -D HASP_LOG_LEVEL=LOG_LEVEL_WARNING
-D HASP_USE_CAPTIVE_PORTAL=0
; -D HASP_USE_CUSTOM=1
- ; -D MQTT_TOPIC_CUSTOM="SmartPICoop"
-
${elecrow-esp32-s3-tft.build_flags}
${elecrow-tft-common-pins.build_flags}
@@ -120,4 +118,78 @@ build_flags =
-D I2C_TOUCH_FREQUENCY=400000
lib_deps =
- ${elecrow-esp32-s3-tft.lib_deps}
\ No newline at end of file
+ ${elecrow-esp32-s3-tft.lib_deps}
+
+
+[env:elecrow-s3-8048c050_4MB]
+; https://forum.elecrow.com/index.php?p=/discussion/585/esp32-hmi-demo-code-updated-compatible-with-new-version-of-esp32-package/
+extends = elecrow-esp32-s3-tft, flash_4mb
+
+build_flags =
+ -D HASP_MODEL="Elecrow WZ8048C050"
+ -D HASP_LOG_LEVEL=LOG_LEVEL_WARNING
+ -D HASP_USE_CAPTIVE_PORTAL=0
+ ; -D HASP_USE_CUSTOM=1
+
+ ${elecrow-esp32-s3-tft.build_flags}
+
+ ; Panel Settings
+ -D TFT_WIDTH=800
+ -D TFT_HEIGHT=480
+
+ ; Bus Settings - LovyanGFX Library
+ -D LGFX_USE_V1=1
+ -D RGB_DRIVER=1
+
+ -D TFT_DE=40
+ -D TFT_VSYNC=41
+ -D TFT_HSYNC=39
+ -D TFT_PCLK=0
+
+ -D TFT_R0=45
+ -D TFT_R1=48
+ -D TFT_R2=47
+ -D TFT_R3=21
+ -D TFT_R4=14
+
+ -D TFT_G0=5
+ -D TFT_G1=6
+ -D TFT_G2=7
+ -D TFT_G3=15
+ -D TFT_G4=16
+ -D TFT_G5=4
+
+ -D TFT_B0=8
+ -D TFT_B1=3
+ -D TFT_B2=46
+ -D TFT_B3=9
+ -D TFT_B4=1
+
+ -D TFT_HSYNC_POLARITY=0
+ -D TFT_HSYNC_FRONT_PORCH=8
+ -D TFT_HSYNC_PULSE_WIDTH=4
+ -D TFT_HSYNC_BACK_PORCH=43
+ -D TFT_VSYNC_POLARITY=0
+ -D TFT_VSYNC_FRONT_PORCH=8
+ -D TFT_VSYNC_PULSE_WIDTH=4
+ -D TFT_VSYNC_BACK_PORCH=12
+ -D TFT_PCLK_ACTIVE_NEG=1
+ -D TFT_PREFER_SPEED=16000000
+ -D TFT_AUTO_FLUSH=1
+
+ -D TFT_PCLK_ACTIVE_NEG=1
+
+ ; Touch Settings
+ -D HASP_USE_LGFX_TOUCH=1
+ -D TOUCH_WIDTH=800
+ -D TOUCH_HEIGHT=480
+ -D TOUCH_DRIVER=0x911
+ -D TOUCH_SCL=20
+ -D TOUCH_SDA=19
+ -D TOUCH_IRQ=-1
+ -D TOUCH_RST=-1
+ -D I2C_TOUCH_ADDRESS=0x5D
+ -D I2C_TOUCH_FREQUENCY=400000
+
+lib_deps =
+ ${elecrow-esp32-s3-tft.lib_deps}
\ No newline at end of file
From 8b6cd9c0582ac3657b903cb5b526ab44cdae8bca Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Sat, 20 Apr 2024 22:30:33 +0200
Subject: [PATCH 002/142] Allow larger btnmap
---
src/hasp/hasp_attribute.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp
index a3fd9f29..b8b42eca 100644
--- a/src/hasp/hasp_attribute.cpp
+++ b/src/hasp/hasp_attribute.cpp
@@ -98,7 +98,7 @@ const char** my_map_create(const char* payload)
{
// Reserve memory for JsonDocument
// StaticJsonDocument<1024> map_doc;
- size_t maxsize = (128u * ((strlen(payload) / 128) + 1)) + 256;
+ size_t maxsize = (128u * ((strlen(payload) / 128) + 1)) + 1024;
DynamicJsonDocument map_doc(maxsize);
DeserializationError jsonError = deserializeJson(map_doc, payload);
From 92bfd8a5cc4e8bb01cfcf5b761204895e75b5d60 Mon Sep 17 00:00:00 2001
From: yetanothercarbot <55005345+yetanothercarbot@users.noreply.github.com>
Date: Thu, 25 Apr 2024 23:48:34 +1000
Subject: [PATCH 003/142] Initial support (bootloops)
---
src/drv/tft/M5Stack.hpp | 2 +-
src/drv/tft/tft_driver.h | 1 +
src/drv/tft/tft_driver_lovyangfx.cpp | 40 ++++++++++++++++++++-
user_setups/esp32/ttgo-t-watch.ini | 54 ++++++++++++++++++++++++++++
user_setups/esp32c3/2424S012.ini | 36 +++++++++++++++++++
5 files changed, 131 insertions(+), 2 deletions(-)
create mode 100644 user_setups/esp32/ttgo-t-watch.ini
create mode 100644 user_setups/esp32c3/2424S012.ini
diff --git a/src/drv/tft/M5Stack.hpp b/src/drv/tft/M5Stack.hpp
index 8822d724..0bdc9ec0 100644
--- a/src/drv/tft/M5Stack.hpp
+++ b/src/drv/tft/M5Stack.hpp
@@ -17,7 +17,7 @@ Contributors:
/----------------------------------------------------------------------------*/
#pragma once
-#if defined(ARDUINO) && defined(LGFX_USE_V1)
+#if defined(ARDUINO) && defined(LGFX_USE_V1) && !defined(ESP32C3)
#include "Arduino.h"
#include "LovyanGFX.hpp"
diff --git a/src/drv/tft/tft_driver.h b/src/drv/tft/tft_driver.h
index c8bed996..b08cee35 100644
--- a/src/drv/tft/tft_driver.h
+++ b/src/drv/tft/tft_driver.h
@@ -32,6 +32,7 @@ enum lv_hasp_obj_type_t {
TFT_PANEL_RM68140,
TFT_PANEL_RGB,
TFT_PANEL_EPD,
+ TFT_PANEL_GC9A01,
TFT_PANEL_LAST,
};
diff --git a/src/drv/tft/tft_driver_lovyangfx.cpp b/src/drv/tft/tft_driver_lovyangfx.cpp
index 9d6d9a6a..62b5aac8 100644
--- a/src/drv/tft/tft_driver_lovyangfx.cpp
+++ b/src/drv/tft/tft_driver_lovyangfx.cpp
@@ -94,8 +94,12 @@ static lgfx::Bus_Parallel8* init_parallel_8_bus(Preferences* prefs, int8_t data_
cfg.pin_rd = prefs->getInt("rd", TFT_RD);
cfg.pin_wr = prefs->getInt("wr", TFT_WR);
cfg.pin_rs = prefs->getInt("rs", TFT_DC);
+#ifndef ESP32C3
cfg.freq_write = prefs->getUInt("write_freq", SPI_FREQUENCY);
-#if !defined(CONFIG_IDF_TARGET_ESP32S3)
+#endif
+
+
+#if !defined(CONFIG_IDF_TARGET_ESP32S3) && !defined(ESP32C3)
uint8_t port = prefs->getUInt("i2s_port", 0);
switch(port) {
#if SOC_I2S_NUM > 1
@@ -328,6 +332,11 @@ lgfx::Panel_Device* LovyanGfx::_init_panel(lgfx::IBus* bus)
LOG_VERBOSE(TAG_TFT, F("Panel_RGB"));
break;
}
+ case TFT_PANEL_GC9A01: {
+ panel = new lgfx::Panel_GC9A01();
+ LOG_VERBOSE(TAG_TFT, F("Panel_GC9A01"));
+ break;
+ }
default: { // Needs to be in curly braces
LOG_FATAL(TAG_TFT, F(D_SERVICE_START_FAILED ": %s line %d"), __FILE__, __LINE__);
}
@@ -455,6 +464,31 @@ lgfx::ITouch* _init_touch(Preferences* preferences)
}
#endif
+#if TOUCH_DRIVER == 0x816
+ {
+ auto touch = new lgfx::Touch_CST816S();
+ auto cfg = touch->config();
+
+ cfg.x_min = 0;
+ cfg.x_max = TFT_WIDTH - 1;
+ cfg.y_min = 0;
+ cfg.y_max = TFT_HEIGHT - 1;
+ cfg.pin_int = TOUCH_IRQ;
+ cfg.bus_shared = true;
+ cfg.offset_rotation = TOUCH_OFFSET_ROTATION;
+
+ // I2C接続の場合
+ cfg.i2c_port = I2C_TOUCH_PORT;
+ cfg.i2c_addr = I2C_TOUCH_ADDRESS;
+ cfg.pin_sda = TOUCH_SDA;
+ cfg.pin_scl = TOUCH_SCL;
+ cfg.freq = I2C_TOUCH_FREQUENCY;
+
+ touch->config(cfg);
+ return touch;
+ }
+#endif
+
#endif // HASP_USE_LGFX_TOUCH
return nullptr;
@@ -1261,6 +1295,8 @@ const char* LovyanGfx::get_tft_model()
return "R61529";
#elif defined(RM68140_DRIVER)
return "RM68140";
+#elif defined(GC9A01_DRIVER)
+ return "GC9A01";
#else
return "Other";
#endif
@@ -1302,6 +1338,8 @@ uint32_t LovyanGfx::get_tft_driver()
return TFT_PANEL_EPD;
#elif defined(RGB_DRIVER)
return TFT_PANEL_RGB;
+#elif defined(GC9A01_DRIVER)
+ return TFT_PANEL_GC9A01;
#else
return TFT_PANEL_UNKNOWN;
#endif
diff --git a/user_setups/esp32/ttgo-t-watch.ini b/user_setups/esp32/ttgo-t-watch.ini
new file mode 100644
index 00000000..91b114ba
--- /dev/null
+++ b/user_setups/esp32/ttgo-t-watch.ini
@@ -0,0 +1,54 @@
+[ttgo-t-watch]
+
+extends = arduino_esp32_v2
+board = esp32dev
+
+build_flags =
+ ${arduino_esp32_v2.build_flags}
+ ${esp32.ps_ram}
+
+;region -- TFT_eSPI build options ------------------------
+ -D LGFX_USE_V1=1
+ -D HASP_USE_LGFX_TOUCH=1
+ -D ST7789_DRIVER=1
+ -D TFT_HEIGHT=240
+ -D TFT_WIDTH=240
+ -D TFT_DC=27
+ -D TFT_CS=5
+ -D TFT_MOSI=19
+ -D TFT_RST=-1
+ -D TFT_SCLK=18
+ -D TFT_BCKL=12
+ -D SPI_FREQUENCY=40000000
+ -D I2C_TOUCH_ADDRESS=0x38
+ -D I2C_TOUCH_FREQUENCY=400000
+ -D TOUCH_DRIVER=0x6336
+ -D I2C_TOUCH_PORT=1
+ -D TOUCH_IRQ=38
+ -D TOUCH_RST=-1
+ -D TOUCH_SDA=23
+ -D TOUCH_SCL=32
+;endregion
+
+lib_deps =
+ ${arduino_esp32_v2.lib_deps}
+ ${lovyangfx.lib_deps}
+ ${ft6336.lib_deps}
+
+[env:ttgo-t-watch-2019]
+extends = ttgo-t-watch, flash_16mb
+
+build_flags =
+ ${ttgo-t-watch.build_flags}
+ -D HASP_MODEL="TTgo T-Watch 2019"
+ -D INVERT_COLORS=1
+
+[env:ttgo-t-watch-2020]
+extends = ttgo-t-watch, flash_16mb
+
+build_flags =
+ ${ttgo-t-watch.build_flags}
+ -D HASP_MODEL="TTgo T-Watch 2020"
+ -D TFT_ROTATION=0
+ ;-D TFT_ROTATION=2
+ -D TOUCH_OFFSET_ROTATION=4 ; 1=swap xy, 2=invert x, 4=inverty
\ No newline at end of file
diff --git a/user_setups/esp32c3/2424S012.ini b/user_setups/esp32c3/2424S012.ini
new file mode 100644
index 00000000..d05ac04c
--- /dev/null
+++ b/user_setups/esp32c3/2424S012.ini
@@ -0,0 +1,36 @@
+[env:2424S012]
+extends = arduino_esp32c3_v2, flash_4mb
+; Close enough
+board = seeed_xiao_esp32c3
+
+build_flags =
+ -D HASP_MODEL="ESP32-2424S012"
+ ${arduino_esp32c3_v2.build_flags}
+ ${esp32c3.no_ps_ram}
+
+; Display configuration
+ -D ESP32C3=1
+ -D LGFX_USE_V1=1
+ -D HASP_USE_LGFX_TOUCH=1
+ ;CST816S driver
+ -D TOUCH_DRIVER=0x816
+ -D GC9A01_DRIVER=1
+ -D TFT_WIDTH=240
+ -D TFT_HEIGHT=240
+ -D TOUCH_SDA=4
+ -D TOUCH_SCL=5
+ -D TOUCH_IRQ=0
+ -D TOUCH_RST=1
+ -D I2C_TOUCH_FREQUENCY=400000
+ -D I2C_TOUCH_PORT=0
+ -D I2C_TOUCH_ADDRESS=0x15
+ -D TFT_SCLK=6
+ -D TFT_MOSI=7
+ -D TFT_DC=2
+ -D TFT_CS=10
+ -D TFT_BCKL=3
+
+lib_deps =
+ ${arduino_esp32s3_v2.lib_deps}
+ ${lovyangfx.lib_deps}
+; ${tft_espi.lib_deps}
\ No newline at end of file
From 462491a5b28e1c5e7e8a827d414effdc4916bab8 Mon Sep 17 00:00:00 2001
From: yetanothercarbot <55005345+yetanothercarbot@users.noreply.github.com>
Date: Fri, 26 Apr 2024 00:11:54 +1000
Subject: [PATCH 004/142] Use SDK-provided define instead of own
---
src/drv/tft/M5Stack.hpp | 2 +-
src/drv/tft/tft_driver_lovyangfx.cpp | 4 ++--
user_setups/esp32c3/2424S012.ini | 6 ++----
3 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/src/drv/tft/M5Stack.hpp b/src/drv/tft/M5Stack.hpp
index 0bdc9ec0..83a8ccd9 100644
--- a/src/drv/tft/M5Stack.hpp
+++ b/src/drv/tft/M5Stack.hpp
@@ -17,7 +17,7 @@ Contributors:
/----------------------------------------------------------------------------*/
#pragma once
-#if defined(ARDUINO) && defined(LGFX_USE_V1) && !defined(ESP32C3)
+#if defined(ARDUINO) && defined(LGFX_USE_V1) && !defined(CONFIG_IDF_TARGET_ESP32C3)
#include "Arduino.h"
#include "LovyanGFX.hpp"
diff --git a/src/drv/tft/tft_driver_lovyangfx.cpp b/src/drv/tft/tft_driver_lovyangfx.cpp
index 62b5aac8..bc3854f9 100644
--- a/src/drv/tft/tft_driver_lovyangfx.cpp
+++ b/src/drv/tft/tft_driver_lovyangfx.cpp
@@ -94,12 +94,12 @@ static lgfx::Bus_Parallel8* init_parallel_8_bus(Preferences* prefs, int8_t data_
cfg.pin_rd = prefs->getInt("rd", TFT_RD);
cfg.pin_wr = prefs->getInt("wr", TFT_WR);
cfg.pin_rs = prefs->getInt("rs", TFT_DC);
-#ifndef ESP32C3
+#ifndef CONFIG_IDF_TARGET_ESP32C3
cfg.freq_write = prefs->getUInt("write_freq", SPI_FREQUENCY);
#endif
-#if !defined(CONFIG_IDF_TARGET_ESP32S3) && !defined(ESP32C3)
+#if !defined(CONFIG_IDF_TARGET_ESP32S3) && !defined(CONFIG_IDF_TARGET_ESP32C3)
uint8_t port = prefs->getUInt("i2s_port", 0);
switch(port) {
#if SOC_I2S_NUM > 1
diff --git a/user_setups/esp32c3/2424S012.ini b/user_setups/esp32c3/2424S012.ini
index d05ac04c..c3179422 100644
--- a/user_setups/esp32c3/2424S012.ini
+++ b/user_setups/esp32c3/2424S012.ini
@@ -1,6 +1,6 @@
[env:2424S012]
extends = arduino_esp32c3_v2, flash_4mb
-; Close enough
+; Close enough, sets it up to use USB-CDC rather than uart
board = seeed_xiao_esp32c3
build_flags =
@@ -9,7 +9,6 @@ build_flags =
${esp32c3.no_ps_ram}
; Display configuration
- -D ESP32C3=1
-D LGFX_USE_V1=1
-D HASP_USE_LGFX_TOUCH=1
;CST816S driver
@@ -32,5 +31,4 @@ build_flags =
lib_deps =
${arduino_esp32s3_v2.lib_deps}
- ${lovyangfx.lib_deps}
-; ${tft_espi.lib_deps}
\ No newline at end of file
+ ${lovyangfx.lib_deps}
\ No newline at end of file
From 78ac4d95b4a3fc8de642351db2c43b6b1ea17ab8 Mon Sep 17 00:00:00 2001
From: yetanothercarbot <55005345+yetanothercarbot@users.noreply.github.com>
Date: Fri, 26 Apr 2024 01:02:23 +1000
Subject: [PATCH 005/142] Boot without serial connected
---
user_setups/esp32c3/2424S012.ini | 1 +
1 file changed, 1 insertion(+)
diff --git a/user_setups/esp32c3/2424S012.ini b/user_setups/esp32c3/2424S012.ini
index c3179422..7259a624 100644
--- a/user_setups/esp32c3/2424S012.ini
+++ b/user_setups/esp32c3/2424S012.ini
@@ -28,6 +28,7 @@ build_flags =
-D TFT_DC=2
-D TFT_CS=10
-D TFT_BCKL=3
+ -D SERIAL_SPEED=-1 ;otherwise requires serial term to boot first time
lib_deps =
${arduino_esp32s3_v2.lib_deps}
From 660a8bb512d50d218334f8efe72636381e0b56ae Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 13 May 2024 13:44:00 +0200
Subject: [PATCH 006/142] Update ace.js to 1.33.2
---
data/edit.htm | 2 +-
data/script.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/edit.htm b/data/edit.htm
index 4143e51c..a644194a 100644
--- a/data/edit.htm
+++ b/data/edit.htm
@@ -1 +1 @@
-openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
+openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
diff --git a/data/script.js b/data/script.js
index 5e9dc496..2578aad1 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1 @@
-var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.8")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
+var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.33.2")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
From 180cc84ea2abbb9686775b277d6d57be5929436e Mon Sep 17 00:00:00 2001
From: FreeBear
Date: Fri, 17 May 2024 00:09:34 +0100
Subject: [PATCH 007/142] Minor spelling mistake corrected
---
src/hasp_filesystem.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hasp_filesystem.cpp b/src/hasp_filesystem.cpp
index ac39a344..1f9f4953 100644
--- a/src/hasp_filesystem.cpp
+++ b/src/hasp_filesystem.cpp
@@ -180,7 +180,7 @@ void filesystemList()
#else
if(!HASP_FS.begin(true)) { // default vfs path: /littlefs
#endif
- LOG_ERROR(TAG_FILE, F("Flash file system not mouted."));
+ LOG_ERROR(TAG_FILE, F("Flash file system not mounted."));
} else {
LOG_VERBOSE(TAG_FILE, F("Listing files on the internal flash:"));
From 182c8c670b640502f5efbfe973ed4affbd41d65c Mon Sep 17 00:00:00 2001
From: K
Date: Sat, 18 May 2024 19:32:04 -0400
Subject: [PATCH 008/142] Add support for Guition JC4827W543
---
platformio.ini | 2 +-
src/drv/tft/tft_driver_arduinogfx.cpp | 8 +++
src/hasp_gui.cpp | 2 +-
user_setups/esp32s3/guition-jc4827w543.ini | 60 ++++++++++++++++++++++
4 files changed, 70 insertions(+), 2 deletions(-)
create mode 100644 user_setups/esp32s3/guition-jc4827w543.ini
diff --git a/platformio.ini b/platformio.ini
index 444439fc..a003dc93 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -112,7 +112,7 @@ lib_deps =
[arduinogfx]
lib_deps =
- moononournation/GFX Library for Arduino@1.4.0 ; Update needs modification of custom PCA class
+ moononournation/GFX Library for Arduino@1.4.7 ; Update needs modification of custom PCA class
;git+https://github.com/moononournation/Arduino_GFX.git
[tft_espi]
diff --git a/src/drv/tft/tft_driver_arduinogfx.cpp b/src/drv/tft/tft_driver_arduinogfx.cpp
index c946120a..601d841f 100644
--- a/src/drv/tft/tft_driver_arduinogfx.cpp
+++ b/src/drv/tft/tft_driver_arduinogfx.cpp
@@ -85,6 +85,10 @@ void ArduinoGfx::init(int w, int h)
/* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */
tft = new Arduino_RGB_Display(w, h, rgbpanel, 0 /* rotation */, TFT_AUTO_FLUSH, bus, TFT_RST,
st7701_type1_init_operations, sizeof(st7701_type1_init_operations));
+#elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 272) && defined(NV3041A_DRIVER)
+ Arduino_DataBus* bus = new Arduino_ESP32QSPI(TFT_CS, TFT_SCK, TFT_D0, TFT_D1, TFT_D2, TFT_D3);
+ Arduino_GFX* g = new Arduino_NV3041A(bus, TFT_RST, TFT_ROTATION, TFT_IPS);
+ tft = g;
#elif 1
/* Reset is not implemented in the panel */
if(TFT_RST != GFX_NOT_DEFINED) {
@@ -299,6 +303,8 @@ const char* ArduinoGfx::get_tft_model()
return "R61529";
#elif defined(RM68140_DRIVER)
return "RM68140";
+#elif defined(NV3041A_DRIVER)
+ return "NV3041A";
#else
return "Other";
#endif
@@ -336,6 +342,8 @@ uint32_t ArduinoGfx::get_tft_driver()
return 0x61529;
#elif defined(RM68140_DRIVER)
return 0x68140;
+#elif defined(NV3041A_DRIVER)
+ return 0x3041A;
#else
return 0x0;
#endif
diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp
index 13caf317..ebb7870a 100644
--- a/src/hasp_gui.cpp
+++ b/src/hasp_gui.cpp
@@ -341,7 +341,7 @@ void guiSetup()
#endif
gui_hide_pointer(false);
if(mouse_indev != NULL) {
- lv_indev_set_cursor(mouse_indev, cursor); /*Connect the image object to the driver*/
+ lv_indev_set_cursor(mouse_indev, cursor); /*Connect the image object to the driver*/
}
#if HASP_TARGET_ARDUINO
diff --git a/user_setups/esp32s3/guition-jc4827w543.ini b/user_setups/esp32s3/guition-jc4827w543.ini
new file mode 100644
index 00000000..ae5f15e7
--- /dev/null
+++ b/user_setups/esp32s3/guition-jc4827w543.ini
@@ -0,0 +1,60 @@
+;***************************************************;
+; Guition ESP32-S3 TFT 4.3" ;
+; - Custom esp32-s3 board ;
+; - nv3041a 480x272 ;
+; - gt911 touch controller ;
+;***************************************************;
+
+[guition-esp32-s3-tft]
+extends = arduino_esp32s3_v2
+board = esp32-s3-devkitc-1
+board_build.arduino.memory_type = qio_opi
+
+build_flags =
+ ${arduino_esp32s3_v2.build_flags}
+ ${esp32s3.ps_ram}
+ ;-D HASP_MODEL="Guition 4.3\""
+
+;region -- ArduinoGFX build options ------------------------
+ -D HASP_USE_ARDUINOGFX
+ -D NV3041A_DRIVER
+ -D BACKLIGHT_FREQUENCY=50
+ ;endregion
+
+lib_deps =
+ ${arduino_esp32s3_v2.lib_deps}
+ ${arduinogfx.lib_deps}
+ ${goodix.lib_deps}
+
+
+[guition-tft-common-pins]
+build_flags =
+ -D TFT_BCKL=1
+ -D TFT_CS=45
+ -D TFT_SCK=47
+ -D TFT_D0=21
+ -D TFT_D1=48
+ -D TFT_D2=40
+ -D TFT_D3=39
+ -D TFT_RST=GFX_NOT_DEFINED
+ -D TFT_ROTATION=0
+ -D TFT_IPS=true
+ -D TFT_WIDTH=480
+ -D TFT_HEIGHT=272
+
+[guition-jc4827w543]
+extends = guition-esp32-s3-tft
+debug_tool = esp-builtin
+debug_build_flags = -Os # optimize for size
+build_flags =
+ -D HASP_MODEL="Guition ESP32-S3 JC4827W543"
+ ${guition-esp32-s3-tft.build_flags}
+ ${guition-tft-common-pins.build_flags}
+ ; Touch Settings
+ -D TOUCH_DRIVER=0x0911
+ -D TOUCH_SCL=4
+ -D TOUCH_SDA=8
+ -D TOUCH_IRQ=-1
+ -D TOUCH_RST=38
+ -D I2C_TOUCH_FREQUENCY=0
+ -D I2C_TOUCH_ADDRESS=0x5D
\ No newline at end of file
From c70dfe6d424ef0c5b433a4446304f2cd0db7f278 Mon Sep 17 00:00:00 2001
From: FreeBear
Date: Mon, 20 May 2024 15:03:19 +0100
Subject: [PATCH 009/142] Add list of TFT gpio pins so that they can not be
selected for IO.
---
src/drv/tft/tft_driver_arduinogfx.cpp | 98 +++++++++++++++++++++++++++
1 file changed, 98 insertions(+)
diff --git a/src/drv/tft/tft_driver_arduinogfx.cpp b/src/drv/tft/tft_driver_arduinogfx.cpp
index c946120a..e050059c 100644
--- a/src/drv/tft/tft_driver_arduinogfx.cpp
+++ b/src/drv/tft/tft_driver_arduinogfx.cpp
@@ -262,6 +262,104 @@ void IRAM_ATTR ArduinoGfx::flush_pixels(lv_disp_drv_t* disp, const lv_area_t* ar
bool ArduinoGfx::is_driver_pin(uint8_t pin)
{
+ if(false // start condition is always needed
+
+// Use individual checks instead of switch statement, as some case labels could be duplicated
+#ifdef TFT_MOSI
+ || (pin == TFT_MOSI)
+#endif
+#ifdef TFT_MISO
+ || (pin == TFT_MISO)
+#endif
+#ifdef TFT_SCLK
+ || (pin == TFT_SCLK)
+#endif
+#ifdef TFT_CS
+ || (pin == TFT_CS)
+#endif
+#ifdef TFT_DC
+ || (pin == TFT_DC)
+#endif
+#ifdef TFT_DE
+ || (pin == TFT_DE)
+#endif
+#ifdef TFT_PCLK
+ || (pin == TFT_PCLK)
+#endif
+#ifdef TFT_VSYNC
+ || (pin == TFT_VSYNC)
+#endif
+#ifdef TFT_HSYNC
+ || (pin == TFT_HSYNC)
+#endif
+#ifdef TFT_BCKL
+ || (pin == TFT_BCKL)
+#endif
+#ifdef TFT_RST
+ || (pin == TFT_RST)
+#endif
+#ifdef TFT_BUSY
+ || (pin == TFT_BUSY)
+#endif
+#ifdef TFT_RD
+ || (pin == TFT_RD)
+#endif
+#ifdef TFT_R0
+ || (pin == TFT_R0)
+#endif
+#ifdef TFT_R1
+ || (pin == TFT_R1)
+#endif
+#ifdef TFT_R2
+ || (pin == TFT_R2)
+#endif
+#ifdef TFT_R3
+ || (pin == TFT_R3)
+#endif
+#ifdef TFT_R4
+ || (pin == TFT_R4)
+#endif
+#ifdef TFT_G0
+ || (pin == TFT_G0)
+#endif
+#ifdef TFT_G1
+ || (pin == TFT_G1)
+#endif
+#ifdef TFT_G2
+ || (pin == TFT_G2)
+#endif
+#ifdef TFT_G3
+ || (pin == TFT_G3)
+#endif
+#ifdef TFT_G4
+ || (pin == TFT_G4)
+#endif
+#ifdef TFT_B0
+ || (pin == TFT_B0)
+#endif
+#ifdef TFT_B1
+ || (pin == TFT_B1)
+#endif
+#ifdef TFT_B2
+ || (pin == TFT_B2)
+#endif
+#ifdef TFT_B3
+ || (pin == TFT_B3)
+#endif
+#ifdef TFT_B4
+ || (pin == TFT_B4)
+#endif
+ ) {
+ return true;
+ }
+
+#ifdef ARDUINO_ARCH_ESP8266
+#ifndef TFT_SPI_OVERLAP
+ if((pin >= 12) && (pin <= 14)) return true; // HSPI
+#endif
+#endif
+
+ return false;
return false;
}
From 7a3b8d0997fe8367ad27f755f4f07df0a4ea77b4 Mon Sep 17 00:00:00 2001
From: FreeBear
Date: Mon, 20 May 2024 15:30:15 +0100
Subject: [PATCH 010/142] Add the touch gpio pins to the list so that they are
hidden from IO selection.
---
src/drv/tft/tft_driver_arduinogfx.cpp | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/drv/tft/tft_driver_arduinogfx.cpp b/src/drv/tft/tft_driver_arduinogfx.cpp
index e050059c..00847ca3 100644
--- a/src/drv/tft/tft_driver_arduinogfx.cpp
+++ b/src/drv/tft/tft_driver_arduinogfx.cpp
@@ -348,6 +348,18 @@ bool ArduinoGfx::is_driver_pin(uint8_t pin)
#endif
#ifdef TFT_B4
|| (pin == TFT_B4)
+#endif
+#ifdef TOUCH_SDA
+ || (pin == TOUCH_SDA)
+#endif
+#ifdef TOUCH_SCL
+ || (pin == TOUCH_SCL)
+#endif
+#ifdef TOUCH_RST
+ || (pin == TOUCH_RST)
+#endif
+#ifdef TOUCH_IRQ
+ || (pin == TOUCH_IRQ)
#endif
) {
return true;
From 86d45119404b9c7cbca170b911a56c07690dca5c Mon Sep 17 00:00:00 2001
From: K
Date: Mon, 20 May 2024 12:18:33 -0400
Subject: [PATCH 011/142] Fix backlight freq and suffix build target
---
user_setups/esp32s3/guition-jc4827w543.ini | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/user_setups/esp32s3/guition-jc4827w543.ini b/user_setups/esp32s3/guition-jc4827w543.ini
index ae5f15e7..689b764c 100644
--- a/user_setups/esp32s3/guition-jc4827w543.ini
+++ b/user_setups/esp32s3/guition-jc4827w543.ini
@@ -18,7 +18,6 @@ build_flags =
;region -- ArduinoGFX build options ------------------------
-D HASP_USE_ARDUINOGFX
-D NV3041A_DRIVER
- -D BACKLIGHT_FREQUENCY=50
;endregion
lib_deps =
@@ -42,12 +41,12 @@ build_flags =
-D TFT_WIDTH=480
-D TFT_HEIGHT=272
-[guition-jc4827w543]
-extends = guition-esp32-s3-tft
+[guition-jc4827w543c]
+extends = guition-esp32-s3-tft, flash_4mb
debug_tool = esp-builtin
debug_build_flags = -Os # optimize for size
build_flags =
- -D HASP_MODEL="Guition ESP32-S3 JC4827W543"
+ -D HASP_MODEL="Guition ESP32-S3 JC4827W543C"
${guition-esp32-s3-tft.build_flags}
${guition-tft-common-pins.build_flags}
; Touch Settings
@@ -57,4 +56,4 @@ build_flags =
-D TOUCH_IRQ=-1
-D TOUCH_RST=38
-D I2C_TOUCH_FREQUENCY=0
- -D I2C_TOUCH_ADDRESS=0x5D
\ No newline at end of file
+ -D I2C_TOUCH_ADDRESS=0x5D
From ca6d521a0a5d22f4bbb1c6c4b6146dad03fa5584 Mon Sep 17 00:00:00 2001
From: FreeBear
Date: Tue, 21 May 2024 13:14:58 +0100
Subject: [PATCH 012/142] Missing the FILE_SIZE_DIVIDER for gigabits - This
results in the number being printed with the decimal point in the wrong
place.
---
src/hasp/hasp_parser.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/hasp/hasp_parser.cpp b/src/hasp/hasp_parser.cpp
index a44a9741..eee1175d 100644
--- a/src/hasp/hasp_parser.cpp
+++ b/src/hasp/hasp_parser.cpp
@@ -212,6 +212,7 @@ int Parser::format_bytes(size_t filesize, char* buf, size_t len)
return snprintf_P(buf, len, PSTR("%d" D_DECIMAL_POINT "%02d " D_FILE_SIZE_MEGABYTES), filesize / 100,
filesize % 100);
+ filesize = filesize / D_FILE_SIZE_DIVIDER; // multiply by 100 for 2 decimal place
return snprintf_P(buf, len, PSTR("%d" D_DECIMAL_POINT "%02d " D_FILE_SIZE_GIGABYTES), filesize / 100,
filesize % 100);
}
From 3433efbb49bdd1822202b70d4434a8ff5546bd4b Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Tue, 21 May 2024 15:50:57 +0200
Subject: [PATCH 013/142] Update sensecap-indicator-d1
---
user_setups/esp32s3/sensecap-indicator.ini | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/user_setups/esp32s3/sensecap-indicator.ini b/user_setups/esp32s3/sensecap-indicator.ini
index ef64e18d..bc721aba 100644
--- a/user_setups/esp32s3/sensecap-indicator.ini
+++ b/user_setups/esp32s3/sensecap-indicator.ini
@@ -83,8 +83,7 @@ build_flags =
lib_deps =
${arduino_esp32s3_v2.lib_deps}
- ${arduinogfx.lib_deps}
- ; ${ft6336.lib_deps}
+ moononournation/GFX Library for Arduino@1.4.0 ; Update needs modification of custom PCA class ; ${ft6336.lib_deps}
; git+https://github.com/RobTillaart/TCA9555.git
From 909afcf2baf21ecd51f15f50b5135d729e5b56d1 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Tue, 21 May 2024 20:28:56 +0200
Subject: [PATCH 014/142] UPdate ace.js to 1.33.3
---
data/edit.htm | 2 +-
data/script.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/edit.htm b/data/edit.htm
index a644194a..3d0a9e5a 100644
--- a/data/edit.htm
+++ b/data/edit.htm
@@ -1 +1 @@
-openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
+openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
diff --git a/data/script.js b/data/script.js
index 2578aad1..c129c1e6 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1 @@
-var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.33.2")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
+var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.33.3")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
From aa09f4bfd43a396816d902428a12a2b940d2f486 Mon Sep 17 00:00:00 2001
From: FreeBear
Date: Wed, 22 May 2024 00:51:02 +0100
Subject: [PATCH 015/142] Using size_t limits max number to 2^32. When dealing
with SD cards we could be asked to print a uint64 (for example, from
SD.totalGytes()).
---
src/hasp/hasp_parser.cpp | 26 ++++++++++++++------------
src/hasp/hasp_parser.h | 2 +-
2 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/src/hasp/hasp_parser.cpp b/src/hasp/hasp_parser.cpp
index eee1175d..f6db3854 100644
--- a/src/hasp/hasp_parser.cpp
+++ b/src/hasp/hasp_parser.cpp
@@ -197,24 +197,26 @@ bool Parser::is_only_digits(const char* s)
return strlen(s) == digits;
}
-int Parser::format_bytes(size_t filesize, char* buf, size_t len)
+int Parser::format_bytes(uint64_t filesize, char* buf, size_t len)
{
- if(filesize < D_FILE_SIZE_DIVIDER) return snprintf_P(buf, len, PSTR("%d " D_FILE_SIZE_BYTES), filesize);
- filesize = filesize * 100;
+ uint32_t tmp = (uint32_t) filesize; // cast to unsigned int here to saye ugly casts in next line
+ if(filesize < D_FILE_SIZE_DIVIDER) return snprintf_P(buf, len, PSTR("%u " D_FILE_SIZE_BYTES), tmp);
- filesize = filesize / D_FILE_SIZE_DIVIDER; // multiply by 100 for 2 decimal place
+ filesize = filesize / (D_FILE_SIZE_DIVIDER/100); // multiply by 100 for 2 decimal place
+ tmp = (uint32_t) filesize;
if(filesize < D_FILE_SIZE_DIVIDER * 100)
- return snprintf_P(buf, len, PSTR("%d" D_DECIMAL_POINT "%02d " D_FILE_SIZE_KILOBYTES), filesize / 100,
- filesize % 100);
+ return snprintf_P(buf, len, PSTR("%u" D_DECIMAL_POINT "%02u " D_FILE_SIZE_KILOBYTES), tmp / 100,
+ tmp % 100);
- filesize = filesize / D_FILE_SIZE_DIVIDER; // multiply by 100 for 2 decimal place
+ filesize = filesize / D_FILE_SIZE_DIVIDER;
+ tmp = (uint32_t) filesize;
if(filesize < D_FILE_SIZE_DIVIDER * 100)
- return snprintf_P(buf, len, PSTR("%d" D_DECIMAL_POINT "%02d " D_FILE_SIZE_MEGABYTES), filesize / 100,
- filesize % 100);
+ return snprintf_P(buf, len, PSTR("%u" D_DECIMAL_POINT "%02u " D_FILE_SIZE_MEGABYTES), tmp / 100,
+ tmp % 100);
- filesize = filesize / D_FILE_SIZE_DIVIDER; // multiply by 100 for 2 decimal place
- return snprintf_P(buf, len, PSTR("%d" D_DECIMAL_POINT "%02d " D_FILE_SIZE_GIGABYTES), filesize / 100,
- filesize % 100);
+ tmp = (uint32_t) (filesize / D_FILE_SIZE_DIVIDER);
+ return snprintf_P(buf, len, PSTR("%u" D_DECIMAL_POINT "%02u " D_FILE_SIZE_GIGABYTES), tmp / 100,
+ tmp % 100);
}
uint8_t Parser::get_action_id(const char* action)
diff --git a/src/hasp/hasp_parser.h b/src/hasp/hasp_parser.h
index d1c44bea..84dcfd1b 100644
--- a/src/hasp/hasp_parser.h
+++ b/src/hasp/hasp_parser.h
@@ -19,7 +19,7 @@ class Parser {
static bool is_true(const char* s);
static bool is_true(JsonVariant json);
static bool is_only_digits(const char* s);
- static int format_bytes(size_t filesize, char* buf, size_t len);
+ static int format_bytes(uint64_t filesize, char* buf, size_t len);
};
#ifndef ARDUINO
From 33f3c3691576a187057aa98039d8812e77cdfe0b Mon Sep 17 00:00:00 2001
From: FreeBear
Date: Wed, 22 May 2024 11:20:14 +0100
Subject: [PATCH 016/142] Take onboard comment about loss of precision. Using
size_t would have overflowed at (approx) 2^28. But with a uint64_t the limit
is going to be up in the Exbi range (2^60).
---
src/hasp/hasp_parser.cpp | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/hasp/hasp_parser.cpp b/src/hasp/hasp_parser.cpp
index f6db3854..2f79ffb6 100644
--- a/src/hasp/hasp_parser.cpp
+++ b/src/hasp/hasp_parser.cpp
@@ -199,22 +199,24 @@ bool Parser::is_only_digits(const char* s)
int Parser::format_bytes(uint64_t filesize, char* buf, size_t len)
{
+ filesize *= 100; // Warning - If filesize up in the Zi range (2^60), we will overflow.
uint32_t tmp = (uint32_t) filesize; // cast to unsigned int here to saye ugly casts in next line
if(filesize < D_FILE_SIZE_DIVIDER) return snprintf_P(buf, len, PSTR("%u " D_FILE_SIZE_BYTES), tmp);
- filesize = filesize / (D_FILE_SIZE_DIVIDER/100); // multiply by 100 for 2 decimal place
+ filesize /= D_FILE_SIZE_DIVIDER;
tmp = (uint32_t) filesize;
if(filesize < D_FILE_SIZE_DIVIDER * 100)
return snprintf_P(buf, len, PSTR("%u" D_DECIMAL_POINT "%02u " D_FILE_SIZE_KILOBYTES), tmp / 100,
tmp % 100);
- filesize = filesize / D_FILE_SIZE_DIVIDER;
+ filesize /= D_FILE_SIZE_DIVIDER;
tmp = (uint32_t) filesize;
- if(filesize < D_FILE_SIZE_DIVIDER * 100)
+ if(filesize < D_FILE_SIZE_DIVIDER * D_FILE_SIZE_DIVIDER * 100)
return snprintf_P(buf, len, PSTR("%u" D_DECIMAL_POINT "%02u " D_FILE_SIZE_MEGABYTES), tmp / 100,
tmp % 100);
- tmp = (uint32_t) (filesize / D_FILE_SIZE_DIVIDER);
+ filesize /= D_FILE_SIZE_DIVIDER;
+ tmp = (uint32_t) filesize;
return snprintf_P(buf, len, PSTR("%u" D_DECIMAL_POINT "%02u " D_FILE_SIZE_GIGABYTES), tmp / 100,
tmp % 100);
}
From 7dc3de34f82454b255df143facd0c3ce67f1ad7a Mon Sep 17 00:00:00 2001
From: FreeBear
Date: Wed, 22 May 2024 11:56:23 +0100
Subject: [PATCH 017/142] One too many file system dividers used for megabyte
comparison.
---
src/hasp/hasp_parser.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hasp/hasp_parser.cpp b/src/hasp/hasp_parser.cpp
index 2f79ffb6..64e4729f 100644
--- a/src/hasp/hasp_parser.cpp
+++ b/src/hasp/hasp_parser.cpp
@@ -211,7 +211,7 @@ int Parser::format_bytes(uint64_t filesize, char* buf, size_t len)
filesize /= D_FILE_SIZE_DIVIDER;
tmp = (uint32_t) filesize;
- if(filesize < D_FILE_SIZE_DIVIDER * D_FILE_SIZE_DIVIDER * 100)
+ if(filesize < D_FILE_SIZE_DIVIDER * 100)
return snprintf_P(buf, len, PSTR("%u" D_DECIMAL_POINT "%02u " D_FILE_SIZE_MEGABYTES), tmp / 100,
tmp % 100);
From b65bd46b411b44c44a8b51b3310b942a66f7e118 Mon Sep 17 00:00:00 2001
From: FreeBear
Date: Wed, 22 May 2024 12:18:03 +0100
Subject: [PATCH 018/142] 2^60 is Exbi (Ei) not Zebi (Zi)
---
src/hasp/hasp_parser.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hasp/hasp_parser.cpp b/src/hasp/hasp_parser.cpp
index 64e4729f..fb557cc5 100644
--- a/src/hasp/hasp_parser.cpp
+++ b/src/hasp/hasp_parser.cpp
@@ -199,7 +199,7 @@ bool Parser::is_only_digits(const char* s)
int Parser::format_bytes(uint64_t filesize, char* buf, size_t len)
{
- filesize *= 100; // Warning - If filesize up in the Zi range (2^60), we will overflow.
+ filesize *= 100; // Warning - If filesize up in the Ei range (2^60), we will overflow.
uint32_t tmp = (uint32_t) filesize; // cast to unsigned int here to saye ugly casts in next line
if(filesize < D_FILE_SIZE_DIVIDER) return snprintf_P(buf, len, PSTR("%u " D_FILE_SIZE_BYTES), tmp);
From 452c619e97c66698112641503d4a1bb419461e57 Mon Sep 17 00:00:00 2001
From: FreeBear
Date: Wed, 22 May 2024 12:44:36 +0100
Subject: [PATCH 019/142] Use a const char* array for format_bytes suffixes at
the expense of a little more system memory.
---
src/hasp/hasp_parser.cpp | 22 +++++++---------------
1 file changed, 7 insertions(+), 15 deletions(-)
diff --git a/src/hasp/hasp_parser.cpp b/src/hasp/hasp_parser.cpp
index fb557cc5..ae5fe88c 100644
--- a/src/hasp/hasp_parser.cpp
+++ b/src/hasp/hasp_parser.cpp
@@ -203,22 +203,14 @@ int Parser::format_bytes(uint64_t filesize, char* buf, size_t len)
uint32_t tmp = (uint32_t) filesize; // cast to unsigned int here to saye ugly casts in next line
if(filesize < D_FILE_SIZE_DIVIDER) return snprintf_P(buf, len, PSTR("%u " D_FILE_SIZE_BYTES), tmp);
- filesize /= D_FILE_SIZE_DIVIDER;
+ const char* suffix[] = {D_FILE_SIZE_KILOBYTES, D_FILE_SIZE_MEGABYTES, D_FILE_SIZE_GIGABYTES};
+ int n = -1;
+ while (filesize > D_FILE_SIZE_DIVIDER * 100) {
+ n += 1;
+ filesize /= D_FILE_SIZE_DIVIDER;
+ }
tmp = (uint32_t) filesize;
- if(filesize < D_FILE_SIZE_DIVIDER * 100)
- return snprintf_P(buf, len, PSTR("%u" D_DECIMAL_POINT "%02u " D_FILE_SIZE_KILOBYTES), tmp / 100,
- tmp % 100);
-
- filesize /= D_FILE_SIZE_DIVIDER;
- tmp = (uint32_t) filesize;
- if(filesize < D_FILE_SIZE_DIVIDER * 100)
- return snprintf_P(buf, len, PSTR("%u" D_DECIMAL_POINT "%02u " D_FILE_SIZE_MEGABYTES), tmp / 100,
- tmp % 100);
-
- filesize /= D_FILE_SIZE_DIVIDER;
- tmp = (uint32_t) filesize;
- return snprintf_P(buf, len, PSTR("%u" D_DECIMAL_POINT "%02u " D_FILE_SIZE_GIGABYTES), tmp / 100,
- tmp % 100);
+ return snprintf_P(buf, len, PSTR("%u" D_DECIMAL_POINT "%02u %s"), tmp / 100, tmp % 100, suffix[n]);
}
uint8_t Parser::get_action_id(const char* action)
From e37ca4c318e41e767f6d76fff3e2277700146906 Mon Sep 17 00:00:00 2001
From: FreeBear
Date: Wed, 22 May 2024 15:21:44 +0100
Subject: [PATCH 020/142] Just in case file size in the TiB range gets passed,
make sure we don't index beyond the end of the array.
---
src/hasp/hasp_parser.cpp | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/hasp/hasp_parser.cpp b/src/hasp/hasp_parser.cpp
index ae5fe88c..b3966380 100644
--- a/src/hasp/hasp_parser.cpp
+++ b/src/hasp/hasp_parser.cpp
@@ -199,16 +199,18 @@ bool Parser::is_only_digits(const char* s)
int Parser::format_bytes(uint64_t filesize, char* buf, size_t len)
{
- filesize *= 100; // Warning - If filesize up in the Ei range (2^60), we will overflow.
+ filesize *= 102400; // Warning - If filesize up in the Ei range (2^60), we will overflow.
uint32_t tmp = (uint32_t) filesize; // cast to unsigned int here to saye ugly casts in next line
if(filesize < D_FILE_SIZE_DIVIDER) return snprintf_P(buf, len, PSTR("%u " D_FILE_SIZE_BYTES), tmp);
- const char* suffix[] = {D_FILE_SIZE_KILOBYTES, D_FILE_SIZE_MEGABYTES, D_FILE_SIZE_GIGABYTES};
+ const char* suffix[] = {D_FILE_SIZE_KILOBYTES, D_FILE_SIZE_MEGABYTES, D_FILE_SIZE_GIGABYTES, "oops"};
+ #define UNKNOWN_SUFFIX 2
int n = -1;
- while (filesize > D_FILE_SIZE_DIVIDER * 100) {
+ while (filesize > D_FILE_SIZE_DIVIDER * 100 && n < UNKNOWN_SUFFIX) {
n += 1;
filesize /= D_FILE_SIZE_DIVIDER;
}
+
tmp = (uint32_t) filesize;
return snprintf_P(buf, len, PSTR("%u" D_DECIMAL_POINT "%02u %s"), tmp / 100, tmp % 100, suffix[n]);
}
From fcd99682b32358be20f8749741f87cb27f30904a Mon Sep 17 00:00:00 2001
From: FreeBear
Date: Wed, 22 May 2024 15:26:31 +0100
Subject: [PATCH 021/142] Forgot to roll back on a test.
---
src/hasp/hasp_parser.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hasp/hasp_parser.cpp b/src/hasp/hasp_parser.cpp
index b3966380..6177164d 100644
--- a/src/hasp/hasp_parser.cpp
+++ b/src/hasp/hasp_parser.cpp
@@ -199,7 +199,7 @@ bool Parser::is_only_digits(const char* s)
int Parser::format_bytes(uint64_t filesize, char* buf, size_t len)
{
- filesize *= 102400; // Warning - If filesize up in the Ei range (2^60), we will overflow.
+ filesize *= 100; // Warning - If filesize up in the Ei range (2^60), we will overflow.
uint32_t tmp = (uint32_t) filesize; // cast to unsigned int here to saye ugly casts in next line
if(filesize < D_FILE_SIZE_DIVIDER) return snprintf_P(buf, len, PSTR("%u " D_FILE_SIZE_BYTES), tmp);
From cc1d6d9458f326dcdcfc4d50d0f0e23ff1e171b1 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Wed, 22 May 2024 18:28:53 +0200
Subject: [PATCH 022/142] Refactor format_bytes
---
src/hasp/hasp_parser.cpp | 24 ++++++++++++++----------
src/lang/en_US.h | 1 +
2 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/src/hasp/hasp_parser.cpp b/src/hasp/hasp_parser.cpp
index 6177164d..bb29307d 100644
--- a/src/hasp/hasp_parser.cpp
+++ b/src/hasp/hasp_parser.cpp
@@ -199,20 +199,24 @@ bool Parser::is_only_digits(const char* s)
int Parser::format_bytes(uint64_t filesize, char* buf, size_t len)
{
- filesize *= 100; // Warning - If filesize up in the Ei range (2^60), we will overflow.
- uint32_t tmp = (uint32_t) filesize; // cast to unsigned int here to saye ugly casts in next line
- if(filesize < D_FILE_SIZE_DIVIDER) return snprintf_P(buf, len, PSTR("%u " D_FILE_SIZE_BYTES), tmp);
+ const char* suffix[] = {D_FILE_SIZE_BYTES, D_FILE_SIZE_KILOBYTES, D_FILE_SIZE_MEGABYTES, D_FILE_SIZE_GIGABYTES,
+ D_FILE_SIZE_TERABYTES};
+ uint32_t factor;
+ uint16_t remainder = 0;
+ uint8_t i = 0;
+ uint8_t last_index = (sizeof(suffix) / sizeof(suffix[0])) - 1;
- const char* suffix[] = {D_FILE_SIZE_KILOBYTES, D_FILE_SIZE_MEGABYTES, D_FILE_SIZE_GIGABYTES, "oops"};
- #define UNKNOWN_SUFFIX 2
- int n = -1;
- while (filesize > D_FILE_SIZE_DIVIDER * 100 && n < UNKNOWN_SUFFIX) {
- n += 1;
+ while(filesize >= D_FILE_SIZE_DIVIDER && i < last_index) {
+ i += 1;
+ remainder = filesize % D_FILE_SIZE_DIVIDER;
filesize /= D_FILE_SIZE_DIVIDER;
}
- tmp = (uint32_t) filesize;
- return snprintf_P(buf, len, PSTR("%u" D_DECIMAL_POINT "%02u %s"), tmp / 100, tmp % 100, suffix[n]);
+ factor = (uint32_t)filesize;
+ if(i == 0) return snprintf_P(buf, len, PSTR("%u %s"), factor, suffix[i]);
+
+ remainder = remainder * 100 / D_FILE_SIZE_DIVIDER;
+ return snprintf_P(buf, len, PSTR("%u" D_DECIMAL_POINT "%02u %s"), factor, remainder, suffix[i]);
}
uint8_t Parser::get_action_id(const char* action)
diff --git a/src/lang/en_US.h b/src/lang/en_US.h
index 13df8dbc..0ec1b257 100644
--- a/src/lang/en_US.h
+++ b/src/lang/en_US.h
@@ -30,6 +30,7 @@
#define D_FILE_SIZE_KILOBYTES "KiB"
#define D_FILE_SIZE_MEGABYTES "MiB"
#define D_FILE_SIZE_GIGABYTES "GiB"
+#define D_FILE_SIZE_TERABYTES "TiB"
#define D_FILE_SIZE_DIVIDER 1024 // kibi or kilo bytes
#define D_DECIMAL_POINT "." // decimal comma or point
From d2745abb444b64ece37b40ffc201879494f5dc5e Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 22 May 2024 18:33:49 +0200
Subject: [PATCH 023/142] New translations en_us.h (Romanian)
---
src/lang/ro_RO.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lang/ro_RO.h b/src/lang/ro_RO.h
index 13df8dbc..0ec1b257 100644
--- a/src/lang/ro_RO.h
+++ b/src/lang/ro_RO.h
@@ -30,6 +30,7 @@
#define D_FILE_SIZE_KILOBYTES "KiB"
#define D_FILE_SIZE_MEGABYTES "MiB"
#define D_FILE_SIZE_GIGABYTES "GiB"
+#define D_FILE_SIZE_TERABYTES "TiB"
#define D_FILE_SIZE_DIVIDER 1024 // kibi or kilo bytes
#define D_DECIMAL_POINT "." // decimal comma or point
From 6d594e3d53bf7df419e812b70a0061b267f0d61d Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 22 May 2024 18:33:50 +0200
Subject: [PATCH 024/142] New translations en_us.h (French)
---
src/lang/fr_FR.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lang/fr_FR.h b/src/lang/fr_FR.h
index f84d3995..a752cc6b 100644
--- a/src/lang/fr_FR.h
+++ b/src/lang/fr_FR.h
@@ -30,6 +30,7 @@
#define D_FILE_SIZE_KILOBYTES "Kio"
#define D_FILE_SIZE_MEGABYTES "Mio"
#define D_FILE_SIZE_GIGABYTES "Gio"
+#define D_FILE_SIZE_TERABYTES "TiB"
#define D_FILE_SIZE_DIVIDER 1024 // kibi or kilo bytes
#define D_DECIMAL_POINT "," // decimal comma or point
From 13095042dca58b0b4c51e97631838600660cb5cc Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 22 May 2024 18:33:51 +0200
Subject: [PATCH 025/142] New translations en_us.h (Spanish)
---
src/lang/es_ES.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lang/es_ES.h b/src/lang/es_ES.h
index 613e47ba..af77f0d9 100644
--- a/src/lang/es_ES.h
+++ b/src/lang/es_ES.h
@@ -30,6 +30,7 @@
#define D_FILE_SIZE_KILOBYTES "KiB" // new
#define D_FILE_SIZE_MEGABYTES "MiB" // new
#define D_FILE_SIZE_GIGABYTES "GiB" // new
+#define D_FILE_SIZE_TERABYTES "TiB"
#define D_FILE_SIZE_DIVIDER 1024 // new, kibi or kilo bytes
#define D_DECIMAL_POINT "," // new, decimal comma or point
From 0e1d37c8591393ecd0c9250122734c7b85dd4d41 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 22 May 2024 18:33:52 +0200
Subject: [PATCH 026/142] New translations en_us.h (Danish)
---
src/lang/da_DK.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lang/da_DK.h b/src/lang/da_DK.h
index 13df8dbc..0ec1b257 100644
--- a/src/lang/da_DK.h
+++ b/src/lang/da_DK.h
@@ -30,6 +30,7 @@
#define D_FILE_SIZE_KILOBYTES "KiB"
#define D_FILE_SIZE_MEGABYTES "MiB"
#define D_FILE_SIZE_GIGABYTES "GiB"
+#define D_FILE_SIZE_TERABYTES "TiB"
#define D_FILE_SIZE_DIVIDER 1024 // kibi or kilo bytes
#define D_DECIMAL_POINT "." // decimal comma or point
From de4c1875c39ae2eea41a00e0d87945ea250c9fb7 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 22 May 2024 18:33:53 +0200
Subject: [PATCH 027/142] New translations en_us.h (German)
---
src/lang/de_DE.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lang/de_DE.h b/src/lang/de_DE.h
index efd70477..aa83e7b5 100644
--- a/src/lang/de_DE.h
+++ b/src/lang/de_DE.h
@@ -30,6 +30,7 @@
#define D_FILE_SIZE_KILOBYTES "KiB"
#define D_FILE_SIZE_MEGABYTES "MiB"
#define D_FILE_SIZE_GIGABYTES "GiB"
+#define D_FILE_SIZE_TERABYTES "TiB"
#define D_FILE_SIZE_DIVIDER 1024 // kibi or kilo bytes
#define D_DECIMAL_POINT "," // decimal comma or point
From 00df690a160c603776a02f2d3976d1d92d53fb3e Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 22 May 2024 18:33:54 +0200
Subject: [PATCH 028/142] New translations en_us.h (Hungarian)
---
src/lang/hu_HU.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lang/hu_HU.h b/src/lang/hu_HU.h
index 13df8dbc..0ec1b257 100644
--- a/src/lang/hu_HU.h
+++ b/src/lang/hu_HU.h
@@ -30,6 +30,7 @@
#define D_FILE_SIZE_KILOBYTES "KiB"
#define D_FILE_SIZE_MEGABYTES "MiB"
#define D_FILE_SIZE_GIGABYTES "GiB"
+#define D_FILE_SIZE_TERABYTES "TiB"
#define D_FILE_SIZE_DIVIDER 1024 // kibi or kilo bytes
#define D_DECIMAL_POINT "." // decimal comma or point
From c088ddff8e8c75283e20cd9b428dcb4f78c21f87 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 22 May 2024 18:33:55 +0200
Subject: [PATCH 029/142] New translations en_us.h (Dutch)
---
src/lang/nl_NL.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lang/nl_NL.h b/src/lang/nl_NL.h
index 92e22846..79afa3d1 100644
--- a/src/lang/nl_NL.h
+++ b/src/lang/nl_NL.h
@@ -30,6 +30,7 @@
#define D_FILE_SIZE_KILOBYTES "KiB"
#define D_FILE_SIZE_MEGABYTES "MiB"
#define D_FILE_SIZE_GIGABYTES "GiB"
+#define D_FILE_SIZE_TERABYTES "TiB"
#define D_FILE_SIZE_DIVIDER 1024 // kibi or kilo bytes
#define D_DECIMAL_POINT "," // decimal comma or point
From ee5df54676c72dc3409e779f0b61a596f15873b8 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 22 May 2024 18:33:56 +0200
Subject: [PATCH 030/142] New translations en_us.h (Portuguese)
---
src/lang/pt_PT.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lang/pt_PT.h b/src/lang/pt_PT.h
index 265b26f0..f20c21ae 100644
--- a/src/lang/pt_PT.h
+++ b/src/lang/pt_PT.h
@@ -30,6 +30,7 @@
#define D_FILE_SIZE_KILOBYTES "KiB" // new
#define D_FILE_SIZE_MEGABYTES "MiB" // new
#define D_FILE_SIZE_GIGABYTES "GiB" // new
+#define D_FILE_SIZE_TERABYTES "TiB"
#define D_FILE_SIZE_DIVIDER 1024 // new, kibi or kilo bytes
#define D_DECIMAL_POINT "." // new, decimal comma or point
From fba1331c3be4b98fbc2ee338306776d4e1b88805 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 22 May 2024 18:33:57 +0200
Subject: [PATCH 031/142] New translations en_us.h (Chinese Simplified)
---
src/lang/zh_CN.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lang/zh_CN.h b/src/lang/zh_CN.h
index 13df8dbc..0ec1b257 100644
--- a/src/lang/zh_CN.h
+++ b/src/lang/zh_CN.h
@@ -30,6 +30,7 @@
#define D_FILE_SIZE_KILOBYTES "KiB"
#define D_FILE_SIZE_MEGABYTES "MiB"
#define D_FILE_SIZE_GIGABYTES "GiB"
+#define D_FILE_SIZE_TERABYTES "TiB"
#define D_FILE_SIZE_DIVIDER 1024 // kibi or kilo bytes
#define D_DECIMAL_POINT "." // decimal comma or point
From 83bdad83e571df9cf0b4e64464b85d13fa3d00f9 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 22 May 2024 18:33:58 +0200
Subject: [PATCH 032/142] New translations en_us.h (Portuguese, Brazilian)
---
src/lang/pt_BR.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lang/pt_BR.h b/src/lang/pt_BR.h
index 169e3a8d..54121409 100644
--- a/src/lang/pt_BR.h
+++ b/src/lang/pt_BR.h
@@ -30,6 +30,7 @@
#define D_FILE_SIZE_KILOBYTES "KiB"
#define D_FILE_SIZE_MEGABYTES "MiB"
#define D_FILE_SIZE_GIGABYTES "GiB"
+#define D_FILE_SIZE_TERABYTES "TiB"
#define D_FILE_SIZE_DIVIDER 1024 // kibi or kilo bytes
#define D_DECIMAL_POINT "." // decimal comma or point
From 1ea0752004eccd81d1be0b770aee918b319a58df Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 22 May 2024 20:14:23 +0200
Subject: [PATCH 033/142] New translations en_us.h (French)
---
src/lang/fr_FR.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/lang/fr_FR.h b/src/lang/fr_FR.h
index a752cc6b..51183b2f 100644
--- a/src/lang/fr_FR.h
+++ b/src/lang/fr_FR.h
@@ -30,7 +30,7 @@
#define D_FILE_SIZE_KILOBYTES "Kio"
#define D_FILE_SIZE_MEGABYTES "Mio"
#define D_FILE_SIZE_GIGABYTES "Gio"
-#define D_FILE_SIZE_TERABYTES "TiB"
+#define D_FILE_SIZE_TERABYTES "Tio"
#define D_FILE_SIZE_DIVIDER 1024 // kibi or kilo bytes
#define D_DECIMAL_POINT "," // decimal comma or point
@@ -128,7 +128,7 @@
#define D_HTTP_HTTP_SETTINGS "Paramètres HTTP"
#define D_HTTP_FTP_SETTINGS "Paramètres FTP"
#define D_HTTP_WIFI_SETTINGS "Paramètres Wifi"
-#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
+#define D_HTTP_WIREGUARD_SETTINGS "Paramètres WireGuard"
#define D_HTTP_MQTT_SETTINGS "Paramètres MQTT"
#define D_HTTP_GPIO_SETTINGS "Paramètres GPIO"
#define D_HTTP_MDNS_SETTINGS "Paramètres mDNS"
@@ -203,8 +203,8 @@
#define D_INFO_MAC_ADDRESS "Adresse MAC"
#define D_INFO_GATEWAY "Passerelle"
#define D_INFO_DNS_SERVER "Serveur DNS"
-#define D_INFO_ENDPOINT_IP "Endpoint IP"
-#define D_INFO_ENDPOINT_PORT "Endpoint Port"
+#define D_INFO_ENDPOINT_IP "Adresse IP du point final"
+#define D_INFO_ENDPOINT_IP "Port du point final"
#define D_OOBE_MSG "Touchez l'écran pour configurer le WiFi ou branchez ce point d'accès:"
#define D_OOBE_SCAN_TO_CONNECT "Scanner pour se connecter"
@@ -217,8 +217,8 @@
#define D_WIFI_RSSI_WEAK "Faible"
#define D_WIFI_RSSI_BAD "Très mauvais"
-#define D_WG_INITIALIZED "Initialized"
-#define D_WG_BAD_CONFIG "Missing or bad configuration"
+#define D_WG_INITIALIZED "Initialisé"
+#define D_WG_BAD_CONFIG "Configuration manquante ou incorrecte"
#define D_GPIO_SWITCH "Interrupteur"
#define D_GPIO_BUTTON "Bouton"
From 646f8d91fe134f4bccc6e8501f18e7eb01f89ed9 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 22 May 2024 20:14:25 +0200
Subject: [PATCH 034/142] New translations en_us.h (Spanish)
---
src/lang/es_ES.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/lang/es_ES.h b/src/lang/es_ES.h
index af77f0d9..acee2059 100644
--- a/src/lang/es_ES.h
+++ b/src/lang/es_ES.h
@@ -13,7 +13,7 @@
#define D_NO "No" // New
#define D_ERROR_OUT_OF_MEMORY "Memory llena"
-#define D_ERROR_UNKNOWN "Unknown error"
+#define D_ERROR_UNKNOWN "Error desconocido"
#define D_CONFIG_NOT_CHANGED "No hay cambios en la configuración"
#define D_CONFIG_CHANGED "Configuración cambiada"
@@ -128,7 +128,7 @@
#define D_HTTP_HTTP_SETTINGS "Ajustes HTTP"
#define D_HTTP_HTTP_SETTINGS "Ajustes FTP"
#define D_HTTP_WIFI_SETTINGS "Ajustes Wifi"
-#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
+#define D_HTTP_GUI_SETTINGS "Ajustes WireGuard"
#define D_HTTP_MQTT_SETTINGS "Ajustes MQTT"
#define D_HTTP_GPIO_SETTINGS "Ajustes GPIO"
#define D_HTTP_MDNS_SETTINGS "Ajustes mDNS"
@@ -203,8 +203,8 @@
#define D_INFO_MAC_ADDRESS "Dirección MAC"
#define D_INFO_GATEWAY "Gateway"
#define D_INFO_DNS_SERVER "Servidor DNS"
-#define D_INFO_ENDPOINT_IP "Endpoint IP"
-#define D_INFO_ENDPOINT_PORT "Endpoint Port"
+#define D_INFO_ENDPOINT_IP "IP de punto final"
+#define D_INFO_ENDPOINT_PORT "Puerto de punto final"
#define D_OOBE_MSG "Toque la pantalla para ajustar WiFi o conectarse a un punto de acceso"
#define D_OOBE_SCAN_TO_CONNECT "Scanee para conectar"
@@ -217,8 +217,8 @@
#define D_WIFI_RSSI_WEAK "Débil"
#define D_WIFI_RSSI_BAD "Muy baka"
-#define D_WG_INITIALIZED "Initialized"
-#define D_WG_BAD_CONFIG "Missing or bad configuration"
+#define D_WG_INITIALIZED "Inicializado"
+#define D_WG_BAD_CONFIG "Falta o mala configuración"
#define D_GPIO_SWITCH "Switch"
#define D_GPIO_BUTTON "Botón"
From 331c1d503d45c940353023b9470f3f421a0aa4ef Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 22 May 2024 20:14:28 +0200
Subject: [PATCH 035/142] New translations en_us.h (Portuguese)
---
src/lang/pt_PT.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/lang/pt_PT.h b/src/lang/pt_PT.h
index f20c21ae..757a1e2f 100644
--- a/src/lang/pt_PT.h
+++ b/src/lang/pt_PT.h
@@ -128,7 +128,7 @@
#define D_HTTP_HTTP_SETTINGS "Configurar HTTP"
#define D_HTTP_FTP_SETTINGS "Configurar FTP"
#define D_HTTP_WIFI_SETTINGS "Configurar Wifi"
-#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
+#define D_HTTP_WIREGUARD_SETTINGS "Configurar WireGuard"
#define D_HTTP_MQTT_SETTINGS "Configurar MQTT"
#define D_HTTP_GPIO_SETTINGS "Configurar GPIO"
#define D_HTTP_MDNS_SETTINGS "Configurar mDNS"
@@ -217,8 +217,8 @@
#define D_WIFI_RSSI_BAD "Muito baixo"
#define D_WIFI_RSSI_FAIR "Decente"
-#define D_WG_INITIALIZED "Initialized"
-#define D_WG_BAD_CONFIG "Missing or bad configuration"
+#define D_WG_INITIALIZED "Inicializado"
+#define D_WG_BAD_CONFIG "Configuração ausente ou ruim"
#define D_GPIO_SWITCH "Interruptor"
#define D_GPIO_BUTTON "Botão"
From 92f682c6bd8620ae1222dc8f85d546dba0b6183e Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 22 May 2024 20:14:30 +0200
Subject: [PATCH 036/142] New translations en.json (French)
---
data/fr_FR.json | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/data/fr_FR.json b/data/fr_FR.json
index 7247c2f6..aacaead0 100644
--- a/data/fr_FR.json
+++ b/data/fr_FR.json
@@ -86,13 +86,13 @@
"ssid": "SSID"
},
"wg": {
- "title": "WireGuard Settings",
- "btn": "WireGuard Settings",
- "vpnip": "VPN IP",
- "privkey": "Private Key",
- "host": "Remote IP",
- "port": "Remote Port",
- "pubkey": "Remote Public Key"
+ "title": "Paramètres WireGuard",
+ "btn": "Paramètres WireGuard",
+ "vpnip": "IP du VPN",
+ "privkey": "Clé Privée",
+ "host": "Adresse IP distante",
+ "port": "Port Distant",
+ "pubkey": "Clé publique distante"
},
"mqtt": {
"title": "Paramètres MQTT",
From 983cf13fd0903ba9bc583fedfeb993e8b0b4ce76 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 22 May 2024 20:14:31 +0200
Subject: [PATCH 037/142] New translations en.json (Spanish)
---
data/es_ES.json | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/data/es_ES.json b/data/es_ES.json
index fa1292a2..7df5c933 100644
--- a/data/es_ES.json
+++ b/data/es_ES.json
@@ -86,13 +86,13 @@
"ssid": "SSID"
},
"wg": {
- "title": "WireGuard Settings",
- "btn": "WireGuard Settings",
- "vpnip": "VPN IP",
- "privkey": "Private Key",
- "host": "Remote IP",
- "port": "Remote Port",
- "pubkey": "Remote Public Key"
+ "title": "Ajustes de WireGuard",
+ "btn": "Ajustes de WireGuard",
+ "vpnip": "IP VPN",
+ "privkey": "Clave Privada",
+ "host": "IP Remota",
+ "port": "Puerto Remoto",
+ "pubkey": "Clave Pública Remota"
},
"mqtt": {
"title": "Ajustes MQTT",
From cd3fa42fc09538c895e02f18ba20eda917da8700 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Wed, 22 May 2024 20:38:51 +0200
Subject: [PATCH 038/142] Update ace.js to 1.34.0
---
data/edit.htm | 2 +-
data/script.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/edit.htm b/data/edit.htm
index 3d0a9e5a..e15ab495 100644
--- a/data/edit.htm
+++ b/data/edit.htm
@@ -1 +1 @@
-openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
+openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
diff --git a/data/script.js b/data/script.js
index c129c1e6..670b0d92 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1 @@
-var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.33.3")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
+var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.34.0")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
From 27a0e7ce7321d58064d4528539a2d90c767a0f6d Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 23 May 2024 16:12:46 +0200
Subject: [PATCH 039/142] Add jc4827w543c_4MB
---
.github/workflows/build.yaml | 2 +-
user_setups/esp32s3/guition-jc4827w543.ini | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index d4104b2e..8a8a5054 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -35,7 +35,7 @@ jobs:
- out: globalsecurity
env: gs-t3e_16MB
- out: guition
- env: esp32-s3-4848s040_16MB
+ env: esp32-s3-4848s040_16MB -e guition-jc4827w543c_4MB
- out: lanbon
env: lanbon_l8
- out: lilygo-ttgo
diff --git a/user_setups/esp32s3/guition-jc4827w543.ini b/user_setups/esp32s3/guition-jc4827w543.ini
index 689b764c..5a3721df 100644
--- a/user_setups/esp32s3/guition-jc4827w543.ini
+++ b/user_setups/esp32s3/guition-jc4827w543.ini
@@ -41,7 +41,7 @@ build_flags =
-D TFT_WIDTH=480
-D TFT_HEIGHT=272
-[guition-jc4827w543c]
+[guition-jc4827w543c_4MB]
extends = guition-esp32-s3-tft, flash_4mb
debug_tool = esp-builtin
debug_build_flags = -Os # optimize for size
From 6f402cb42dca5717306197e09549ac4a32617bca Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 23 May 2024 16:17:50 +0200
Subject: [PATCH 040/142] Add guition-jc4827w543c_4MB
---
user_setups/esp32s3/guition-jc4827w543.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/user_setups/esp32s3/guition-jc4827w543.ini b/user_setups/esp32s3/guition-jc4827w543.ini
index 5a3721df..0d41565c 100644
--- a/user_setups/esp32s3/guition-jc4827w543.ini
+++ b/user_setups/esp32s3/guition-jc4827w543.ini
@@ -41,7 +41,7 @@ build_flags =
-D TFT_WIDTH=480
-D TFT_HEIGHT=272
-[guition-jc4827w543c_4MB]
+[env:guition-jc4827w543c_4MB]
extends = guition-esp32-s3-tft, flash_4mb
debug_tool = esp-builtin
debug_build_flags = -Os # optimize for size
From cd34d8994fc1c720982c8c4c2b2044a4d16cf1a7 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 24 May 2024 00:09:52 +0200
Subject: [PATCH 041/142] Add elecrow-s3-8048c050_4MB
---
.github/workflows/build.yaml | 2 +-
user_setups/esp32s3/crowpanel-hmi.ini | 6 ------
2 files changed, 1 insertion(+), 7 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 8a8a5054..64838bd1 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -31,7 +31,7 @@ jobs:
- out: dustinwatts
env: "freetouchdeck_4MB -e freetouchdeck_8MB -e esp32-touchdown"
- out: elecrow
- env: "esp32-terminal-rgb_16MB -e esp32-terminal-spi_16MB -e elecrow-s3-8048c070_4MB"
+ env: "esp32-terminal-rgb_16MB -e esp32-terminal-spi_16MB -e elecrow-s3-8048c050_4MB -e elecrow-s3-8048c070_4MB"
- out: globalsecurity
env: gs-t3e_16MB
- out: guition
diff --git a/user_setups/esp32s3/crowpanel-hmi.ini b/user_setups/esp32s3/crowpanel-hmi.ini
index 5a6be7c0..74ebc05c 100644
--- a/user_setups/esp32s3/crowpanel-hmi.ini
+++ b/user_setups/esp32s3/crowpanel-hmi.ini
@@ -81,9 +81,6 @@ extends = elecrow-esp32-s3-tft, flash_4mb
build_flags =
-D HASP_MODEL="Elecrow WZ8048C070"
- -D HASP_LOG_LEVEL=LOG_LEVEL_WARNING
- -D HASP_USE_CAPTIVE_PORTAL=0
- ; -D HASP_USE_CUSTOM=1
${elecrow-esp32-s3-tft.build_flags}
${elecrow-tft-common-pins.build_flags}
@@ -127,9 +124,6 @@ extends = elecrow-esp32-s3-tft, flash_4mb
build_flags =
-D HASP_MODEL="Elecrow WZ8048C050"
- -D HASP_LOG_LEVEL=LOG_LEVEL_WARNING
- -D HASP_USE_CAPTIVE_PORTAL=0
- ; -D HASP_USE_CUSTOM=1
${elecrow-esp32-s3-tft.build_flags}
From a9d514b04c5553a7e4bedc6f79df5a947a590268 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 24 May 2024 04:12:41 +0200
Subject: [PATCH 042/142] Flakey WiFi on Sunton #592
---
user_setups/esp32s3/sunton-esp32-s3-tft.ini | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/user_setups/esp32s3/sunton-esp32-s3-tft.ini b/user_setups/esp32s3/sunton-esp32-s3-tft.ini
index 1da68da7..5c4e9139 100644
--- a/user_setups/esp32s3/sunton-esp32-s3-tft.ini
+++ b/user_setups/esp32s3/sunton-esp32-s3-tft.ini
@@ -142,7 +142,7 @@ build_flags =
-D TFT_VSYNC_PULSE_WIDTH=4 ; Typical VSYNC Pulse Width
-D TFT_VSYNC_BACK_PORCH=8 ; Typical VSYNC Back Porch
-D TFT_PCLK_ACTIVE_NEG=1
- -D TFT_PREFER_SPEED=14000000 ; 1/2 of Typical DCLK Frequency
+ -D TFT_PREFER_SPEED=13900000 ; 1/2 of Typical DCLK Frequency
-D TFT_AUTO_FLUSH=1
; Touch Settings
-D TOUCH_WIDTH=480
@@ -180,7 +180,7 @@ build_flags =
-D TFT_VSYNC_PULSE_WIDTH=4 ; Typical VSYNC Pulse Width
-D TFT_VSYNC_BACK_PORCH=8 ; Typical VSYNC Back Porch
-D TFT_PCLK_ACTIVE_NEG=1
- -D TFT_PREFER_SPEED=14000000 ; 1/2 of Typical DCLK Frequency
+ -D TFT_PREFER_SPEED=13900000 ; 1/2 of Typical DCLK Frequency
-D TFT_AUTO_FLUSH=1
; Touch Settings
-D TOUCH_WIDTH=800
@@ -229,15 +229,15 @@ build_flags =
-D TFT_B4=4
; Panel Settings
-D TFT_HSYNC_POLARITY=0
- -D TFT_HSYNC_FRONT_PORCH=8 ; Maximum HSYNC Front Porch / 8 GOOD
- -D TFT_HSYNC_PULSE_WIDTH=10 ; Typical HSYNC Pulse Width / 10 GOOD
- -D TFT_HSYNC_BACK_PORCH=43 ; Typical HSYNC Back Porch / 43 GOOD
+ -D TFT_HSYNC_FRONT_PORCH=8 ; Maximum HSYNC Front Porch / 8 GOOD
+ -D TFT_HSYNC_PULSE_WIDTH=10 ; Typical HSYNC Pulse Width / 10 GOOD
+ -D TFT_HSYNC_BACK_PORCH=43 ; Typical HSYNC Back Porch / 43 GOOD
-D TFT_VSYNC_POLARITY=0
-D TFT_VSYNC_FRONT_PORCH=8 ; Maximum VSYNC Front Porch / 8 GOOD
-D TFT_VSYNC_PULSE_WIDTH=8 ; Typical VSYNC Pulse Width / 8 GOOD
- -D TFT_VSYNC_BACK_PORCH=12 ; Typical VSYNC Back Porch / 12 GOOD
+ -D TFT_VSYNC_BACK_PORCH=12 ; Typical VSYNC Back Porch / 12 GOOD
-D TFT_PCLK_ACTIVE_NEG=1
- -D TFT_PREFER_SPEED=14500000 ; 1/2 of Typical DCLK Frequency / 12000000 GOOD
+ -D TFT_PREFER_SPEED=13900000 ; 1/2 of Typical DCLK Frequency / 12000000 GOOD
-D TFT_AUTO_FLUSH=1
; Touch Settings
-D TOUCH_WIDTH=800
From 1f471ad308028d92af30b63a524b7e1e2e782b32 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 24 May 2024 05:03:53 +0200
Subject: [PATCH 043/142] Add custom_state_subtopic #611
---
src/custom/my_custom_fan_template.cpp | 4 ++++
src/custom/my_custom_template.cpp | 5 +++++
src/custom/my_custom_template.h | 5 +++++
src/hasp/hasp_dispatch.cpp | 12 +++++++++++-
4 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/src/custom/my_custom_fan_template.cpp b/src/custom/my_custom_fan_template.cpp
index b7bed86d..a8775242 100644
--- a/src/custom/my_custom_fan_template.cpp
+++ b/src/custom/my_custom_fan_template.cpp
@@ -98,4 +98,8 @@ void custom_topic_payload(const char* topic, const char* payload, uint8_t source
// LOG_VERBOSE(TAG_CUSTOM, "Handled custom message: %s => %s", topic, payload);
}
+void custom_state_subtopic(const char* subtopic, const char* payload){
+ // Not used
+}
+
#endif // HASP_USE_CUSTOM
diff --git a/src/custom/my_custom_template.cpp b/src/custom/my_custom_template.cpp
index b41da916..358bbd0f 100644
--- a/src/custom/my_custom_template.cpp
+++ b/src/custom/my_custom_template.cpp
@@ -53,4 +53,9 @@ void custom_topic_payload(const char* topic, const char* payload, uint8_t source
// Not used
}
+void custom_state_subtopic(const char* subtopic, const char* payload){
+ // Not used
+}
+
+
#endif // HASP_USE_CUSTOM
\ No newline at end of file
diff --git a/src/custom/my_custom_template.h b/src/custom/my_custom_template.h
index 111df88f..3e25c031 100644
--- a/src/custom/my_custom_template.h
+++ b/src/custom/my_custom_template.h
@@ -32,6 +32,11 @@ void custom_get_sensors(JsonDocument& doc);
/* Receive custom topic & payload messages */
void custom_topic_payload(const char* topic, const char* payload, uint8_t source);
+/* Get notified when a state message is sent out */
+/* Can be used to send state changes through other means then MQTT, e.g. Serial2 */
+/* https://github.com/HASwitchPlate/openHASP/issues/611 */
+void custom_state_subtopic(const char* subtopic, const char* payload);
+
#endif // HASP_USE_CUSTOM
#endif // HASP_CUSTOM_H
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index 03b0da9d..39ddae76 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -43,7 +43,7 @@ uint16_t dispatchSecondsToNextTeleperiod = 0;
uint16_t dispatchSecondsToNextSensordata = 0;
uint16_t dispatchSecondsToNextDiscovery = 0;
uint8_t nCommands = 0;
-haspCommand_t commands[28];
+haspCommand_t commands[29];
moodlight_t moodlight = {.brightness = 255};
uint8_t saved_jsonl_page = 0;
@@ -74,6 +74,10 @@ void dispatch_state_subtopic(const char* subtopic, const char* payload)
}
#endif
+#if HASP_USE_CUSTOM > 0
+ custom_state_subtopic(subtopic, payload);
+#endif
+
#if HASP_USE_TASMOTA_CLIENT > 0
slave_send_state(subtopic, payload);
#endif
@@ -864,6 +868,11 @@ void dispatch_run_script(const char*, const char* payload, uint8_t source)
#endif
}
+void dispatch_dir(const char*, const char* payload, uint8_t source)
+{
+ filesystem_list_path(payload);
+}
+
#if HASP_TARGET_PC
static void shell_command_thread(char* cmdline)
{
@@ -1592,6 +1601,7 @@ void dispatchSetup()
dispatch_add_command(PSTR("sensors"), dispatch_send_sensordata);
dispatch_add_command(PSTR("theme"), dispatch_theme);
dispatch_add_command(PSTR("run"), dispatch_run_script);
+ dispatch_add_command(PSTR("dir"), dispatch_dir);
#if HASP_TARGET_PC
dispatch_add_command(PSTR("shell"), dispatch_shell_execute);
#endif
From 5c80f41fcfa53c08239d4a98acd046d20f2f18e3 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 24 May 2024 05:14:49 +0200
Subject: [PATCH 044/142] Add custom_state_subtopic
---
src/hasp/hasp_dispatch.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index 39ddae76..72c6b4f0 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -52,7 +52,7 @@ uint8_t saved_jsonl_page = 0;
*/
void dispatch_state_subtopic(const char* subtopic, const char* payload)
{
-#if HASP_USE_MQTT == 0 && HASP_USE_TASMOTA_CLIENT == 0
+#if HASP_USE_MQTT == 0 && defined(HASP_USE_TASMOTA_CLIENT) && HASP_USE_TASMOTA_CLIENT > 0
LOG_TRACE(TAG_MSGR, F("%s => %s"), subtopic, payload);
#else
@@ -74,15 +74,15 @@ void dispatch_state_subtopic(const char* subtopic, const char* payload)
}
#endif
-#if HASP_USE_CUSTOM > 0
- custom_state_subtopic(subtopic, payload);
-#endif
-
-#if HASP_USE_TASMOTA_CLIENT > 0
+#if defined(HASP_USE_TASMOTA_CLIENT) && HASP_USE_TASMOTA_CLIENT > 0
slave_send_state(subtopic, payload);
#endif
#endif
+
+#if defined(HASP_USE_CUSTOM) && HASP_USE_CUSTOM > 0
+ custom_state_subtopic(subtopic, payload);
+#endif
}
void dispatch_state_eventid(const char* topic, hasp_event_t eventid)
From 8a341fd09cedcc217355092ef575f56fdf2d08ff Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 24 May 2024 13:50:15 +0200
Subject: [PATCH 045/142] Update ace.js to 1.34.1
---
data/edit.htm | 2 +-
data/script.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/edit.htm b/data/edit.htm
index e15ab495..4d1ccace 100644
--- a/data/edit.htm
+++ b/data/edit.htm
@@ -1 +1 @@
-openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
+openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
diff --git a/data/script.js b/data/script.js
index 670b0d92..e9705de1 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1 @@
-var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.34.0")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
+var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.34.1")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
From d903bc905fb76859852f2c0d92ff6a80e234b8a9 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 24 May 2024 21:39:57 +0200
Subject: [PATCH 046/142] Add mqttEverySecond
---
src/hasp/hasp_task.cpp | 4 ++++
src/main.cpp | 4 ++++
src/mqtt/hasp_mqtt.h | 1 +
src/mqtt/hasp_mqtt_esp.cpp | 18 +++++++++++-------
src/mqtt/hasp_mqtt_paho_async.cpp | 2 --
src/mqtt/hasp_mqtt_pubsubclient.cpp | 4 ++--
6 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/src/hasp/hasp_task.cpp b/src/hasp/hasp_task.cpp
index a6d01900..272285d7 100644
--- a/src/hasp/hasp_task.cpp
+++ b/src/hasp/hasp_task.cpp
@@ -24,6 +24,10 @@ void task_every_second_cb(lv_task_t* task)
{
haspEverySecond(); // sleep timer & statusupdate
+#if HASP_MQTT_TELNET > 0
+ mqttEverySecond();
+#endif
+
#if HASP_USE_TELNET > 0
telnetEverySecond();
#endif
diff --git a/src/main.cpp b/src/main.cpp
index b065909c..c68c2bf4 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -210,6 +210,10 @@ IRAM_ATTR void loop()
/* Runs Every Second */
haspEverySecond(); // sleep timer & statusupdate
+#if HASP_USE_MQTT > 0
+ mqttEverySecond();
+#endif
+
#if HASP_USE_FTP > 0
ftpEverySecond();
#endif
diff --git a/src/mqtt/hasp_mqtt.h b/src/mqtt/hasp_mqtt.h
index f5d57196..89ced6c1 100644
--- a/src/mqtt/hasp_mqtt.h
+++ b/src/mqtt/hasp_mqtt.h
@@ -18,6 +18,7 @@ typedef enum {
void mqttSetup();
IRAM_ATTR void mqttLoop();
+void mqttEverySecond();
void mqttEvery5Seconds(bool wifiIsConnected);
void mqttStart();
void mqttStop();
diff --git a/src/mqtt/hasp_mqtt_esp.cpp b/src/mqtt/hasp_mqtt_esp.cpp
index 453d3a33..8864c107 100644
--- a/src/mqtt/hasp_mqtt_esp.cpp
+++ b/src/mqtt/hasp_mqtt_esp.cpp
@@ -71,7 +71,7 @@ bool last_mqtt_state = false;
bool current_mqtt_state = false;
uint16_t mqtt_reconnect_counter = 0;
-void mqtt_run_scripts()
+static inline void mqtt_run_scripts()
{
if(last_mqtt_state != current_mqtt_state) {
// mqtt_message_t data;
@@ -104,8 +104,8 @@ void mqtt_run_scripts()
void mqtt_disconnected()
{
current_mqtt_state = false; // now we are disconnected
- // mqtt_run_scripts();
mqtt_reconnect_counter++;
+ // mqtt_run_scripts(); // must happen in LVGL loop
}
void mqtt_connected()
@@ -115,7 +115,7 @@ void mqtt_connected()
current_mqtt_state = true; // now we are connected
LOG_VERBOSE(TAG_MQTT, F("%s"), current_mqtt_state ? PSTR(D_SERVICE_CONNECTED) : PSTR(D_SERVICE_DISCONNECTED));
}
- // mqtt_run_scripts();
+ // mqtt_run_scripts(); // must happen in LVGL loop
}
int mqttPublish(const char* topic, const char* payload, size_t len, bool retain)
@@ -337,7 +337,7 @@ String mqttGetTopic(Preferences preferences, String subtopic, String key, String
}
*/
-void mqttParseTopic(String *topic, String subtopic, bool add_slash)
+void mqttParseTopic(String* topic, String subtopic, bool add_slash)
{
topic->replace(F("%hostname%"), haspDevice.get_hostname());
@@ -509,10 +509,14 @@ IRAM_ATTR void mqttLoop(void)
}
}
-void mqttEvery5Seconds(bool networkIsConnected)
+void mqttEverySecond()
{
mqtt_run_scripts();
- // if(mqttEnabled && networkIsConnected && !mqttClientConnected) {
+}
+
+void mqttEvery5Seconds(bool networkIsConnected)
+{
+ // if(mqttEnabled && networkIsConnected && !current_mqtt_state) {
// LOG_TRACE(TAG_MQTT, F(D_MQTT_RECONNECTING));
// mqttStart();
// }
@@ -535,7 +539,7 @@ void mqttStart()
nvsOldGroup += preferences.getString(FP_CONFIG_GROUP, MQTT_GROUPNAME);
nvsOldGroup += "/%topic%";
- subtopic = F(MQTT_TOPIC_COMMAND);
+ subtopic = F(MQTT_TOPIC_COMMAND);
mqttNodeCommandTopic = preferences.getString(FP_CONFIG_NODE_TOPIC, MQTT_DEFAULT_NODE_TOPIC);
mqttParseTopic(&mqttNodeCommandTopic, subtopic, false);
mqttGroupCommandTopic = preferences.getString(FP_CONFIG_GROUP_TOPIC, nvsOldGroup.c_str());
diff --git a/src/mqtt/hasp_mqtt_paho_async.cpp b/src/mqtt/hasp_mqtt_paho_async.cpp
index 6c4e35f2..fe1c0d47 100644
--- a/src/mqtt/hasp_mqtt_paho_async.cpp
+++ b/src/mqtt/hasp_mqtt_paho_async.cpp
@@ -3,8 +3,6 @@
/* Multi threaded asynchronous paho client */
-#include
-
#include "hasp_conf.h"
#if HASP_USE_MQTT_ASYNC > 0
diff --git a/src/mqtt/hasp_mqtt_pubsubclient.cpp b/src/mqtt/hasp_mqtt_pubsubclient.cpp
index 29e11b2f..9acd5ce8 100644
--- a/src/mqtt/hasp_mqtt_pubsubclient.cpp
+++ b/src/mqtt/hasp_mqtt_pubsubclient.cpp
@@ -14,10 +14,10 @@
#if defined(ARDUINO_ARCH_ESP32)
#include
-#include
+// #include
WiFiClient mqttNetworkClient;
// WiFiClientSecure mqttNetworkClient;
-extern const uint8_t rootca_crt_bundle_start[] asm("_binary_data_cert_x509_crt_bundle_bin_start");
+// extern const uint8_t rootca_crt_bundle_start[] asm("_binary_data_cert_x509_crt_bundle_bin_start");
#elif defined(ARDUINO_ARCH_ESP8266)
#include
#include
From f175dc599aa2741141d946439fc1410670837f17 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 24 May 2024 21:58:15 +0200
Subject: [PATCH 047/142] Prepare LVFS support for /sdcard
---
include/lv_conf_v7.h | 4 ++--
lib/lv_fs_if/lv_fs_if.c | 18 ++++++++++++++----
lib/lv_fs_if/lv_fs_pc.c | 28 ++++++++++------------------
user_setups/esp32/_esp32.ini | 2 +-
user_setups/esp32s2/_esp32s2.ini | 2 +-
5 files changed, 28 insertions(+), 26 deletions(-)
diff --git a/include/lv_conf_v7.h b/include/lv_conf_v7.h
index 764be7bd..606203cc 100644
--- a/include/lv_conf_v7.h
+++ b/include/lv_conf_v7.h
@@ -211,7 +211,7 @@ typedef void* lv_group_user_data_t;
#define LV_USE_FILESYSTEM 1
#if LV_USE_FILESYSTEM
/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/
-typedef void* lv_fs_drv_user_data_t;
+typedef const char* lv_fs_drv_user_data_t;
/*File system interface*/
#ifndef LV_USE_FS_IF
@@ -229,7 +229,7 @@ typedef void* lv_fs_drv_user_data_t;
//# define LV_FS_IF_SPIFFS '\0' // no internal esp Flash
#endif
#endif /*LV_USE_FS_IF*/
-#if HASP_TARGET_ARDUINO
+#if HASP_TARGET_ARDUINO && !defined(LV_FS_PC_PATH)
#define LV_FS_PC_PATH "/littlefs"
#endif
diff --git a/lib/lv_fs_if/lv_fs_if.c b/lib/lv_fs_if/lv_fs_if.c
index 472edcf2..45c94def 100644
--- a/lib/lv_fs_if/lv_fs_if.c
+++ b/lib/lv_fs_if/lv_fs_if.c
@@ -14,6 +14,13 @@
/*********************
* DEFINES
*********************/
+#ifndef LV_FS_PC_PATH
+#ifndef WIN32
+#define LV_FS_PC_PATH "./" /*Project root*/
+#else
+#define LV_FS_PC_PATH ".\\" /*Project root*/
+#endif
+#endif /*LV_FS_PATH*/
/**********************
* TYPEDEFS
@@ -26,8 +33,8 @@
void lv_fs_if_fatfs_init(void);
#endif
-#if LV_FS_IF_PC != '\0'
-void lv_fs_if_pc_init(void);
+#if LV_FS_IF_PC != '\0' || LV_FS_IF_SD != '\0'
+void lv_fs_if_pc_init(char letter, const char* path);
#endif
/**********************
@@ -48,13 +55,16 @@ void lv_fs_if_pc_init(void);
void lv_fs_if_init(void)
{
#if LV_FS_IF_FATFS != '\0'
- lv_fs_if_fatfs_init();
+ lv_fs_if_fatfs_init();
#endif
#if LV_FS_IF_PC != '\0'
- lv_fs_if_pc_init();
+ lv_fs_if_pc_init(LV_FS_IF_PC, LV_FS_PC_PATH);
#endif
+#if LV_FS_IF_SD != '\0'
+ lv_fs_if_pc_init(LV_FS_IF_SD, LV_FS_SD_PATH);
+#endif
}
/**********************
diff --git a/lib/lv_fs_if/lv_fs_pc.c b/lib/lv_fs_if/lv_fs_pc.c
index 02aa1a41..b83e1ac3 100644
--- a/lib/lv_fs_if/lv_fs_pc.c
+++ b/lib/lv_fs_if/lv_fs_pc.c
@@ -19,17 +19,6 @@
#include
#endif
-/*********************
- * DEFINES
- *********************/
-#ifndef LV_FS_PC_PATH
-#ifndef WIN32
-#define LV_FS_PC_PATH "./" /*Projet root*/
-#else
-#define LV_FS_PC_PATH ".\\" /*Projet root*/
-#endif
-#endif /*LV_FS_PATH*/
-
/**********************
* TYPEDEFS
**********************/
@@ -77,7 +66,7 @@ static lv_fs_res_t fs_dir_close(lv_fs_drv_t* drv, void* dir_p);
/**
* Register a driver for the File system interface
*/
-void lv_fs_if_pc_init(void)
+void lv_fs_if_pc_init(char letter, const char* path)
{
/*---------------------------------------------------
* Register the file system interface in LittlevGL
@@ -107,6 +96,8 @@ void lv_fs_if_pc_init(void)
fs_drv.dir_open_cb = fs_dir_open;
fs_drv.dir_read_cb = fs_dir_read;
+ fs_drv.user_data = LV_FS_PC_PATH;
+
lv_fs_drv_register(&fs_drv);
// char cur_path[512] = "";
@@ -145,10 +136,10 @@ static lv_fs_res_t fs_open(lv_fs_drv_t* drv, void* file_p, const char* path, lv_
#ifndef WIN32
char buf[256];
- sprintf(buf, LV_FS_PC_PATH "/%s", path);
+ sprintf(buf, "%s/%s", drv->user_data, path);
#else
char buf[256];
- sprintf(buf, LV_FS_PC_PATH "\\%s", path);
+ sprintf(buf, "%s\\%s", drv->user_data, path);
#endif
LV_LOG_USER(buf);
@@ -255,6 +246,7 @@ static lv_fs_res_t fs_size(lv_fs_drv_t* drv, void* file_p, uint32_t* size_p)
return LV_FS_RES_OK;
}
+
/**
* Give the position of the read write pointer
* @param drv pointer to a driver where this function belongs
@@ -318,8 +310,8 @@ static lv_fs_res_t fs_rename(lv_fs_drv_t* drv, const char* oldname, const char*
static char new[512];
static char old[512];
- sprintf(old, LV_FS_PC_PATH "/%s", oldname);
- sprintf(new, LV_FS_PC_PATH "/%s", newname);
+ sprintf(old, "%s/%s", drv->user_data, oldname);
+ sprintf(new, "%s/%s", drv->user_data, newname);
int r = rename(old, new);
@@ -365,7 +357,7 @@ static lv_fs_res_t fs_dir_open(lv_fs_drv_t* drv, void* dir_p, const char* path)
#ifndef WIN32
/*Make the path relative to the current directory (the projects root folder)*/
char buf[256];
- sprintf(buf, LV_FS_PC_PATH "/%s", path);
+ sprintf(buf, "%s/%s", drv->user_data, path);
if((d = opendir(buf)) == NULL) {
return LV_FS_RES_FS_ERR;
} else {
@@ -380,7 +372,7 @@ static lv_fs_res_t fs_dir_open(lv_fs_drv_t* drv, void* dir_p, const char* path)
/*Make the path relative to the current directory (the projects root folder)*/
char buf[256];
- sprintf(buf, LV_FS_PC_PATH "\\%s\\*", path);
+ sprintf(buf, "%s\\%s\\*", drv->user_data, path);
strcpy(next_fn, "");
d = FindFirstFile(buf, &fdata);
diff --git a/user_setups/esp32/_esp32.ini b/user_setups/esp32/_esp32.ini
index 780997e5..93079589 100644
--- a/user_setups/esp32/_esp32.ini
+++ b/user_setups/esp32/_esp32.ini
@@ -45,7 +45,7 @@ build_flags =
-D LV_ATTRIBUTE_FAST_MEM=IRAM_ATTR
-D LV_ATTRIBUTE_TASK_HANDLER=IRAM_ATTR
-D LV_USE_FS_IF=1
- ;-D LV_FS_PC_PATH="//littlefs" ; this needs to match the vfs mount pount
+ -D LV_FS_PC_PATH='"/littlefs"' ; this needs to match the vfs mount pount
; -- ArduinoJson build options ----------------------------
-D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments
; -- tft_espi build options ------------------------
diff --git a/user_setups/esp32s2/_esp32s2.ini b/user_setups/esp32s2/_esp32s2.ini
index 0cfc0156..7b042521 100644
--- a/user_setups/esp32s2/_esp32s2.ini
+++ b/user_setups/esp32s2/_esp32s2.ini
@@ -15,7 +15,7 @@ build_flags =
-D LV_ATTRIBUTE_FAST_MEM=
-D LV_ATTRIBUTE_TASK_HANDLER=IRAM_ATTR
-D LV_USE_FS_IF=1
- ;-D LV_FS_PC_PATH="//littlefs" ; this needs to match the vfs mount pount
+ -D LV_FS_PC_PATH='"/littlefs"' ; this needs to match the vfs mount pount
; -- ArduinoJson build options ----------------------------
-D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments
; -- tft_espi build options ------------------------
From b118e5624531d85e071ff8a55c15f53e1192118d Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 24 May 2024 22:06:17 +0200
Subject: [PATCH 048/142] Fix for lv_fs_if_pc_init
---
lib/lv_fs_if/lv_fs_pc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/lv_fs_if/lv_fs_pc.c b/lib/lv_fs_if/lv_fs_pc.c
index b83e1ac3..cca7afbd 100644
--- a/lib/lv_fs_if/lv_fs_pc.c
+++ b/lib/lv_fs_if/lv_fs_pc.c
@@ -78,7 +78,7 @@ void lv_fs_if_pc_init(char letter, const char* path)
/*Set up fields...*/
fs_drv.file_size = sizeof(file_t);
- fs_drv.letter = LV_FS_IF_PC;
+ fs_drv.letter = letter;
fs_drv.open_cb = fs_open;
fs_drv.close_cb = fs_close;
fs_drv.read_cb = fs_read;
@@ -96,7 +96,7 @@ void lv_fs_if_pc_init(char letter, const char* path)
fs_drv.dir_open_cb = fs_dir_open;
fs_drv.dir_read_cb = fs_dir_read;
- fs_drv.user_data = LV_FS_PC_PATH;
+ fs_drv.user_data = path;
lv_fs_drv_register(&fs_drv);
From 944f92e588b9ca9fb5c177d0b253d386a788df8b Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 24 May 2024 22:18:57 +0200
Subject: [PATCH 049/142] Add mqttEverySecond
---
src/mqtt/hasp_mqtt_paho_async.cpp | 7 +++++--
src/mqtt/hasp_mqtt_paho_single.cpp | 3 +++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/mqtt/hasp_mqtt_paho_async.cpp b/src/mqtt/hasp_mqtt_paho_async.cpp
index fe1c0d47..28b81d10 100644
--- a/src/mqtt/hasp_mqtt_paho_async.cpp
+++ b/src/mqtt/hasp_mqtt_paho_async.cpp
@@ -45,7 +45,7 @@ const char FP_CONFIG_GROUP[] PROGMEM = "group";
#include "hasp_mqtt.h" // functions to implement here
#include "hasp/hasp_dispatch.h" // for dispatch_topic_payload
-#include "hasp_debug.h" // for logging
+#include "hasp_debug.h" // for logging
#if !defined(_WIN32)
#include
@@ -436,7 +436,10 @@ void mqttSetup()
mqttLwtTopic += MQTT_TOPIC_LWT;
}
-IRAM_ATTR void mqttLoop(){};
+IRAM_ATTR void mqttLoop() {};
+
+void mqttEverySecond()
+{}
void mqttEvery5Seconds(bool wifiIsConnected)
{
diff --git a/src/mqtt/hasp_mqtt_paho_single.cpp b/src/mqtt/hasp_mqtt_paho_single.cpp
index 653a884f..50044044 100644
--- a/src/mqtt/hasp_mqtt_paho_single.cpp
+++ b/src/mqtt/hasp_mqtt_paho_single.cpp
@@ -391,6 +391,9 @@ IRAM_ATTR void mqttLoop()
if(rc == MQTTCLIENT_SUCCESS && message) mqtt_message_arrived(mqtt_client, topicName, topicLen, message);
};
+void mqttEverySecond()
+{}
+
void mqttEvery5Seconds(bool wifiIsConnected)
{
if(!mqttIsConnected()) {
From 57207c7119cfc7c3ad5ee4d4723eb956480cdd10 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 27 May 2024 17:11:00 +0200
Subject: [PATCH 050/142] Update ace.js to 1.34.2
---
data/edit.htm | 2 +-
data/script.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/edit.htm b/data/edit.htm
index 4d1ccace..41bcd04b 100644
--- a/data/edit.htm
+++ b/data/edit.htm
@@ -1 +1 @@
-openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
+openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
diff --git a/data/script.js b/data/script.js
index e9705de1..da51ed7d 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1 @@
-var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.34.1")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
+var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.34.2")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
From c4217a92e893ee7f9d57438220647998639b5bde Mon Sep 17 00:00:00 2001
From: adampr1
Date: Thu, 30 May 2024 17:12:30 +0200
Subject: [PATCH 051/142] Add support for Waveshare ESP32-S3-Touch-LCD-4.3
Add suppor for ws_esp32_s3_touch_lcd_4p3 from post https://github.com/HASwitchPlate/openHASP/discussions/602
---
platformio_override-template.ini | 1 +
1 file changed, 1 insertion(+)
diff --git a/platformio_override-template.ini b/platformio_override-template.ini
index 69a865c2..c3791ae8 100644
--- a/platformio_override-template.ini
+++ b/platformio_override-template.ini
@@ -78,6 +78,7 @@ extra_default_envs =
; wt-86-32-3zw1
; yeacreate-nscreen32
; wz2432r028
+ ; ws_esp32_s3_touch_lcd_4p3
;endregion
;region -- Define your local COM ports for each environment ---
From 91074746039acdb7e90b5ac58988ffd3c0ea090e Mon Sep 17 00:00:00 2001
From: adampr1
Date: Thu, 30 May 2024 17:14:42 +0200
Subject: [PATCH 052/142] Add support for Waveshare ESP32-S3-Touch-LCD-4.3
Add support for Waveshare ESP32-S3-Touch-LCD-4.3 from https://github.com/HASwitchPlate/openHASP/discussions/602
---
.../esp32s3/ws_esp32_s3_touch_lcd_4p3.ini | 86 +++++++++++++++++++
1 file changed, 86 insertions(+)
create mode 100644 user_setups/esp32s3/ws_esp32_s3_touch_lcd_4p3.ini
diff --git a/user_setups/esp32s3/ws_esp32_s3_touch_lcd_4p3.ini b/user_setups/esp32s3/ws_esp32_s3_touch_lcd_4p3.ini
new file mode 100644
index 00000000..fd766e4a
--- /dev/null
+++ b/user_setups/esp32s3/ws_esp32_s3_touch_lcd_4p3.ini
@@ -0,0 +1,86 @@
+;***************************************************;
+; Waveshare ESP32-S3-Touch-LCD-4.3 ;
+; - 16-bit RGB TFT ;
+; - GT911 touch controller ;
+;***************************************************;
+
+
+[ws_esp32_s3_touch]
+extends = arduino_esp32s3_v2, flash_8mb
+board = esp32-s3-devkitc-1
+board_build.arduino.memory_type = qio_opi
+
+build_flags =
+ ${arduino_esp32s3_v2.build_flags}
+ ${esp32s3.ps_ram}
+ ;-DARDUINO_USB_CDC_ON_BOOT
+ ;-DUSE_USB_CDC_CONSOLE
+
+;region -- ArduinoGFX build options ------------------------
+ -D HASP_USE_ARDUINOGFX=1
+ -D HASP_LV_USE_SW_ROTATE=1
+;endregion
+
+lib_deps =
+ ${arduino_esp32s3_v2.lib_deps}
+ ${arduinogfx.lib_deps}
+ Arduino_RPi_DPI_RGBPanel_mod
+ ${goodix.lib_deps}
+
+[env:ws_esp32_s3_touch_lcd_4p3]
+extends = ws_esp32_s3_touch
+
+build_flags =
+ -D HASP_MODEL="Waveshare ESP32-S3-Touch-LCD-4.3"
+ ${ws_esp32_s3_touch.build_flags}
+ ; Bus Settings
+ -D LV_VDB_SIZE=76800 ; 10% of full framebuffer
+ -D TFT_WIDTH=800
+ -D TFT_HEIGHT=480
+ -D TFT_DE=5
+ -D TFT_VSYNC=3
+ -D TFT_HSYNC=46
+ -D TFT_PCLK=7
+ -D TFT_B0=14
+ -D TFT_B1=38
+ -D TFT_B2=18
+ -D TFT_B3=17
+ -D TFT_B4=10
+ -D TFT_G0=39
+ -D TFT_G1=0
+ -D TFT_G2=45
+ -D TFT_G3=48
+ -D TFT_G4=47
+ -D TFT_G5=21
+ -D TFT_R0=1
+ -D TFT_R1=2
+ -D TFT_R2=42
+ -D TFT_R3=41
+ -D TFT_R4=40
+ -D TFT_BCKL=6 ; use GPIO06 as backlight PIN
+ ; Panel Settings
+ -D TFT_HSYNC_POLARITY=0
+ -D TFT_HSYNC_FRONT_PORCH=20 ; Maximum HSYNC Front Porch
+ -D TFT_HSYNC_PULSE_WIDTH=10 ; Typical HSYNC Pulse Width
+ -D TFT_HSYNC_BACK_PORCH=10 ; Typical HSYNC Back Porch
+ -D TFT_VSYNC_POLARITY=0
+ -D TFT_VSYNC_FRONT_PORCH=10 ; Maximum VSYNC Front Porch
+ -D TFT_VSYNC_PULSE_WIDTH=10 ; Typical VSYNC Pulse Width
+ -D TFT_VSYNC_BACK_PORCH=10 ; Typical VSYNC Back Porch
+ -D TFT_PCLK_ACTIVE_NEG=0
+ -D TFT_PREFER_SPEED=14000000 ; 1/2 of Typical DCLK Frequency
+ -D TFT_AUTO_FLUSH=1
+ ; Touch Settings
+ -D TOUCH_WIDTH=800
+ -D TOUCH_HEIGHT=480
+ -D TOUCH_DRIVER=0x911
+ -D TOUCH_SCL=9
+ -D TOUCH_SDA=8
+ -D TOUCH_IRQ=-1
+ -D TOUCH_RST=-1
+ -D I2C_TOUCH_ADDRESS=0x5d ; or 0x5D
+ -D I2C_TOUCH_FREQUENCY=400000
+ -D BACKLIGHT_FREQUENCY=1000 ;adopted frerquency for MP3302DJ-LF-Z (200 to 1000Hz) ->higher is better for sound!
+lib_deps =
+ ${sunton-esp32-s3-tft.lib_deps}
+ ${goodix.lib_deps}
From 94ceaf2cf132d1e1bef4b231ecac40f99779a9a6 Mon Sep 17 00:00:00 2001
From: FreeBear
Date: Fri, 14 Jun 2024 00:03:26 +0100
Subject: [PATCH 053/142] Was a mistake to hide TFT_BCKL gpio pin from the
user. On some boards, it can be reassigned by the user (on others, it is
baked in to the hardware).
---
src/drv/tft/tft_driver_arduinogfx.cpp | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/drv/tft/tft_driver_arduinogfx.cpp b/src/drv/tft/tft_driver_arduinogfx.cpp
index f9fc214f..4bc12004 100644
--- a/src/drv/tft/tft_driver_arduinogfx.cpp
+++ b/src/drv/tft/tft_driver_arduinogfx.cpp
@@ -296,9 +296,6 @@ bool ArduinoGfx::is_driver_pin(uint8_t pin)
#ifdef TFT_HSYNC
|| (pin == TFT_HSYNC)
#endif
-#ifdef TFT_BCKL
- || (pin == TFT_BCKL)
-#endif
#ifdef TFT_RST
|| (pin == TFT_RST)
#endif
From 20256b2953bf58edb07fc3e5a00e4e0bb6b9d97b Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 18 Jul 2024 20:03:07 +0200
Subject: [PATCH 054/142] Update ace.js to v1.35.3
---
data/edit.htm | 2 +-
data/script.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/edit.htm b/data/edit.htm
index 41bcd04b..1a112286 100644
--- a/data/edit.htm
+++ b/data/edit.htm
@@ -1 +1 @@
-openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
+openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
diff --git a/data/script.js b/data/script.js
index da51ed7d..93a1d96d 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1 @@
-var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.34.2")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
+var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.35.3")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
From 89ef57346a8f8aa51df4b243f8cba9f224cda2a4 Mon Sep 17 00:00:00 2001
From: FreeBear
Date: Fri, 19 Jul 2024 15:20:11 +0100
Subject: [PATCH 055/142] TFT_G5 was missing from the list of used GPIO pins.
Add the USB TX/RX pins to the list for the Guition ESP32-S3 4848S040 board.
---
src/drv/tft/tft_driver_arduinogfx.cpp | 9 +++++++++
user_setups/esp32s3/esp32-s3-4848S040.ini | 4 ++++
2 files changed, 13 insertions(+)
diff --git a/src/drv/tft/tft_driver_arduinogfx.cpp b/src/drv/tft/tft_driver_arduinogfx.cpp
index 4bc12004..a1cc3c89 100644
--- a/src/drv/tft/tft_driver_arduinogfx.cpp
+++ b/src/drv/tft/tft_driver_arduinogfx.cpp
@@ -335,6 +335,9 @@ bool ArduinoGfx::is_driver_pin(uint8_t pin)
#ifdef TFT_G4
|| (pin == TFT_G4)
#endif
+#ifdef TFT_G5
+ || (pin == TFT_G5)
+#endif
#ifdef TFT_B0
|| (pin == TFT_B0)
#endif
@@ -361,6 +364,12 @@ bool ArduinoGfx::is_driver_pin(uint8_t pin)
#endif
#ifdef TOUCH_IRQ
|| (pin == TOUCH_IRQ)
+#endif
+#ifdef USB_TXD
+ || (pin == USB_TXD)
+#endif
+#ifdef USB_RXD
+ || (pin == USB_RXD)
#endif
) {
return true;
diff --git a/user_setups/esp32s3/esp32-s3-4848S040.ini b/user_setups/esp32s3/esp32-s3-4848S040.ini
index 95c800ac..27d89050 100644
--- a/user_setups/esp32s3/esp32-s3-4848S040.ini
+++ b/user_setups/esp32s3/esp32-s3-4848S040.ini
@@ -76,6 +76,10 @@ build_flags =
-D I2C_TOUCH_FREQUENCY=400000
-D I2C_TOUCH_ADDRESS=0x5D ; or 0x14
-D I2C_TOUCH_PORT=1
+ ; USB GPIO - Only need to define these so that the pins do not
+ ; show up in the list of available GPIO
+ -D USB_TXD=43
+ -D USB_RXD=44
;endregion
lib_deps =
From 0b30b075fa806b13ceeff7058654d41745e7685c Mon Sep 17 00:00:00 2001
From: FreeBear
Date: Fri, 19 Jul 2024 16:15:45 +0100
Subject: [PATCH 056/142] Move USB_TXD/RXD to is_system_pin()
---
src/drv/tft/tft_driver_arduinogfx.cpp | 6 ------
1 file changed, 6 deletions(-)
diff --git a/src/drv/tft/tft_driver_arduinogfx.cpp b/src/drv/tft/tft_driver_arduinogfx.cpp
index a1cc3c89..ae73d504 100644
--- a/src/drv/tft/tft_driver_arduinogfx.cpp
+++ b/src/drv/tft/tft_driver_arduinogfx.cpp
@@ -364,12 +364,6 @@ bool ArduinoGfx::is_driver_pin(uint8_t pin)
#endif
#ifdef TOUCH_IRQ
|| (pin == TOUCH_IRQ)
-#endif
-#ifdef USB_TXD
- || (pin == USB_TXD)
-#endif
-#ifdef USB_RXD
- || (pin == USB_RXD)
#endif
) {
return true;
From 734f11d3d8596d43d889fc60958346067ac5c385 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 22 Jul 2024 16:44:12 +0200
Subject: [PATCH 057/142] Update ace?js to v1.35.4
---
data/edit.htm | 2 +-
data/script.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/edit.htm b/data/edit.htm
index 1a112286..c0a35dc2 100644
--- a/data/edit.htm
+++ b/data/edit.htm
@@ -1 +1 @@
-openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
+openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
diff --git a/data/script.js b/data/script.js
index 93a1d96d..afd735c2 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1 @@
-var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.35.3")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
+var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.35.4")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
From 348852476ddc87aa14776b64eb8b2439654b7433 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Tue, 23 Jul 2024 22:28:36 +0200
Subject: [PATCH 058/142] Use "event" group for pushbuttons in discovery {
---
src/hasp/hasp_dispatch.cpp | 44 ++++++++++++++++++++++++++++++++++----
src/sys/gpio/hasp_gpio.cpp | 8 +++++--
src/sys/gpio/hasp_gpio.h | 2 +-
3 files changed, 47 insertions(+), 7 deletions(-)
diff --git a/src/hasp/hasp_dispatch.cpp b/src/hasp/hasp_dispatch.cpp
index 72c6b4f0..33cffc77 100644
--- a/src/hasp/hasp_dispatch.cpp
+++ b/src/hasp/hasp_dispatch.cpp
@@ -868,10 +868,45 @@ void dispatch_run_script(const char*, const char* payload, uint8_t source)
#endif
}
-void dispatch_dir(const char*, const char* payload, uint8_t source)
+/*
+void dispatch_fs(const char*, const char* payload, uint8_t source)
{
- filesystem_list_path(payload);
+ StaticJsonDocument<512> json;
+
+ // Note: Deserialization needs to be (const char *) so the objects WILL be copied
+ // this uses more memory but otherwise the mqtt receive buffer can get overwritten by the send buffer !!
+ DeserializationError jsonError = deserializeJson(json, payload);
+ // json.shrinkToFit();
+
+ if(!jsonError && json.is()) { // Only JsonObject is valid
+ JsonVariant action;
+
+ const char* cmd = json["cmd"].as();
+ const char* src = json["src"].as();
+ const char* dst = json["dst"].as();
+ int res = 0;
+
+ if(String(cmd) == "stat") {
+ res = filesystem_vfs_file_exists(src);
+ }
+ if(String(cmd) == "rm") {
+ res = filesystem_vfs_delete_file(src);
+ }
+ if(String(cmd) == "cp") {
+ res = filesystem_vfs_copy_file(src, dst);
+ }
+ if(String(cmd) == "ls") {
+ filesystem_list_path(src);
+ }
+
+ if(res) {
+ LOG_WARNING(TAG_MSGR, "Succes");
+ } else {
+ LOG_WARNING(TAG_MSGR, "Failed");
+ }
+ }
}
+*/
#if HASP_TARGET_PC
static void shell_command_thread(char* cmdline)
@@ -1327,9 +1362,10 @@ void dispatch_get_discovery_data(JsonDocument& doc)
JsonArray relay = doc.createNestedArray(F("power"));
JsonArray led = doc.createNestedArray(F("light"));
JsonArray dimmer = doc.createNestedArray(F("dim"));
+ JsonArray event = doc.createNestedArray(F("event"));
#if HASP_USE_GPIO > 0
- gpio_discovery(input, relay, led, dimmer);
+ gpio_discovery(input, relay, led, dimmer, event);
#endif
}
@@ -1601,7 +1637,7 @@ void dispatchSetup()
dispatch_add_command(PSTR("sensors"), dispatch_send_sensordata);
dispatch_add_command(PSTR("theme"), dispatch_theme);
dispatch_add_command(PSTR("run"), dispatch_run_script);
- dispatch_add_command(PSTR("dir"), dispatch_dir);
+ // dispatch_add_command(PSTR("fs"), dispatch_fs);
#if HASP_TARGET_PC
dispatch_add_command(PSTR("shell"), dispatch_shell_execute);
#endif
diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp
index 0094f80b..69f1feb8 100644
--- a/src/sys/gpio/hasp_gpio.cpp
+++ b/src/sys/gpio/hasp_gpio.cpp
@@ -835,7 +835,7 @@ hasp_gpio_config_t gpioGetPinConfig(uint8_t num)
return gpioConfig[num];
}
-void gpio_discovery(JsonObject& input, JsonArray& relay, JsonArray& light, JsonArray& dimmer)
+void gpio_discovery(JsonObject& input, JsonArray& relay, JsonArray& light, JsonArray& dimmer, JsonArray& event)
{
char description[20] = "";
@@ -848,6 +848,10 @@ void gpio_discovery(JsonObject& input, JsonArray& relay, JsonArray& light, JsonA
case hasp_gpio_type_t::POWER_RELAY:
relay.add(gpioConfig[i].pin);
break;
+
+ case BUTTON ... TOUCH:
+ event.add(gpioConfig[i].pin);
+ break;
case hasp_gpio_type_t::HASP_DAC:
case hasp_gpio_type_t::LED: // Don't include the moodlight
@@ -857,8 +861,8 @@ void gpio_discovery(JsonObject& input, JsonArray& relay, JsonArray& light, JsonA
dimmer.add(gpioConfig[i].pin);
break;
+ // case BUTTON ... TOUCH:
case SWITCH:
- case BUTTON ... TOUCH:
strcpy_P(description, PSTR("none"));
break;
case BATTERY:
diff --git a/src/sys/gpio/hasp_gpio.h b/src/sys/gpio/hasp_gpio.h
index df093048..105f4460 100644
--- a/src/sys/gpio/hasp_gpio.h
+++ b/src/sys/gpio/hasp_gpio.h
@@ -47,7 +47,7 @@ bool gpio_set_pin_state(uint8_t pin, bool power, int32_t val);
void gpio_set_moodlight(moodlight_t& moodlight);
-void gpio_discovery(JsonObject& input, JsonArray& relay, JsonArray& light, JsonArray& dimmer);
+void gpio_discovery(JsonObject& input, JsonArray& relay, JsonArray& light, JsonArray& dimmer, JsonArray& event);
bool gpioSavePinConfig(uint8_t config_num, uint8_t pin, uint8_t type, uint8_t group, uint8_t pinfunc, bool inverted);
bool gpioIsSystemPin(uint8_t gpio);
From 31572ef9d05722ae53ec72ec57f3b6c1150917fb Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Tue, 23 Jul 2024 22:44:50 +0200
Subject: [PATCH 059/142] Add "event" key to discovery message for push button
events
---
src/sys/gpio/hasp_gpio.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp
index 69f1feb8..693eec7b 100644
--- a/src/sys/gpio/hasp_gpio.cpp
+++ b/src/sys/gpio/hasp_gpio.cpp
@@ -954,8 +954,8 @@ void gpio_discovery(JsonObject& input, JsonArray& relay, JsonArray& light, JsonA
strcpy_P(description, PSTR("unknown"));
}
- if((gpioConfig[i].type >= hasp_gpio_type_t::SWITCH && gpioConfig[i].type <= hasp_gpio_type_t::WINDOW) ||
- (gpioConfig[i].type >= hasp_gpio_type_t::BUTTON && gpioConfig[i].type <= hasp_gpio_type_t::TOUCH)) {
+ if((gpioConfig[i].type >= hasp_gpio_type_t::SWITCH && gpioConfig[i].type <= hasp_gpio_type_t::WINDOW)) {
+ // || (gpioConfig[i].type >= hasp_gpio_type_t::BUTTON && gpioConfig[i].type <= hasp_gpio_type_t::TOUCH)) {
JsonArray arr = input[description];
if(arr.isNull()) arr = input.createNestedArray(description);
arr.add(gpioConfig[i].pin);
From 1ffa7b86368257408199e7e6980a0b3d862c5ff8 Mon Sep 17 00:00:00 2001
From: yetanothercarbot <55005345+yetanothercarbot@users.noreply.github.com>
Date: Tue, 30 Jul 2024 17:56:00 +1000
Subject: [PATCH 060/142] ESP32-S3-BOX-3 support finalised
---
user_setups/esp32s3/esp-box.ini | 47 +++++++++++++++++++++++++--------
1 file changed, 36 insertions(+), 11 deletions(-)
diff --git a/user_setups/esp32s3/esp-box.ini b/user_setups/esp32s3/esp-box.ini
index aff0848e..31899248 100644
--- a/user_setups/esp32s3/esp-box.ini
+++ b/user_setups/esp32s3/esp-box.ini
@@ -4,20 +4,19 @@
; - TT21100 touch controller ;
;***************************************************;
-[env:esp-box]
+[esp_box]
extends = arduino_esp32s3_v2, flash_16mb
-board = esp32s3box
+board = esp32-s3-devkitc-1 ; setting board to 'esp32s3box' breaks ESP32-S3-BOX-3 sadly as that overrides the TFT_RST parameter.
board_build.arduino.memory_type = qio_opi
build_flags =
- -D HASP_MODEL="ESP-BOX"
${arduino_esp32s3_v2.build_flags}
${esp32s3.ps_ram}
-;region -- TFT_eSPI build options ------------------------
+;region -- display build options ------------------------
-D LGFX_USE_V1=1
-D HASP_USE_LGFX_TOUCH=1
- -D TOUCH_DRIVER=0x21100
+
-D ILI9341_DRIVER=1
-D INVERT_COLORS=0
-D TFT_ROTATION=2
@@ -25,21 +24,47 @@ build_flags =
-D TFT_HEIGHT=240
-D TOUCH_SDA=8
-D TOUCH_SCL=18
- -D TOUCH_OFFSET_ROTATION=4 ; 1=swap xy, 2=invert x, 4=inverty
-D TOUCH_IRQ=3
-D I2C_TOUCH_FREQUENCY=400000
- -D I2C_TOUCH_PORT=1
- -D I2C_TOUCH_ADDRESS=0x24
-D TFT_DC=4
-D TFT_CS=5
-D TFT_MOSI=6
+ -D TFT_MISO=-1
-D TFT_SCLK=7
- -D TFT_RST=48
- -D TFT_BCKL=45
-D SPI_FREQUENCY=40000000
+ ; -D SERIAL_SPEED=-1
;endregion
lib_deps =
${arduino_esp32s3_v2.lib_deps}
${lovyangfx.lib_deps}
- ${tft_espi.lib_deps}
+
+
+[env:esp32-s3-box]
+extends = esp_box
+
+build_flags =
+ -D HASP_MODEL="ESP32-S3-BOX"
+ ${esp_box.build_flags}
+
+ -D TOUCH_DRIVER=0x21100
+ -D I2C_TOUCH_ADDRESS=0x24
+ -D I2C_TOUCH_PORT=1
+ -D TOUCH_OFFSET_ROTATION=4 ; 1=swap xy axis (rotate), 2=invert x, 4=inverty
+ -D TFT_BCKL=45
+ -D TFT_RST=48
+
+; GPIO1 for mute status
+[env:esp32-s3-box-3]
+extends = esp_box
+
+build_flags =
+ -D HASP_MODEL="ESP32-S3-BOX-3"
+ ${esp_box.build_flags}
+
+ -D TOUCH_DRIVER=0x911
+ -D I2C_TOUCH_ADDRESS=0x14
+ -D I2C_TOUCH_PORT=0
+ -D TOUCH_OFFSET_ROTATION=2 ; 1=swap xy axis (rotate), 2=invert x, 4=inverty
+ -D TFT_BCKL=47
+ -D TFT_RST=-1
\ No newline at end of file
From 8b173815c9dd545fcd64ae642d31fe60bda6cb61 Mon Sep 17 00:00:00 2001
From: GiorgioAresu
Date: Sun, 11 Aug 2024 22:37:28 +0200
Subject: [PATCH 061/142] Add devcontainer configuration
---
.devcontainer/devcontainer.json | 35 ++++++++++++++++++++++++++++++++
.github/dependabot.yml | 12 +++++++++++
platformio_override-template.ini | 5 ++++-
3 files changed, 51 insertions(+), 1 deletion(-)
create mode 100644 .devcontainer/devcontainer.json
create mode 100644 .github/dependabot.yml
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 00000000..505ce0d9
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,35 @@
+// For format details, see https://aka.ms/devcontainer.json. For config options, see the
+// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu
+{
+ "name": "Ubuntu",
+ // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
+ "image": "mcr.microsoft.com/devcontainers/base:jammy",
+
+ // Features to add to the dev container. More info: https://containers.dev/features.
+ "features": {
+ "ghcr.io/devcontainers/features/python:1": {}
+ },
+
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
+ // "forwardPorts": [],
+
+ // Use 'postCreateCommand' to run commands after the container is created.
+ // "postCreateCommand": "uname -a",
+
+ // Configure tool-specific properties.
+ "customizations": {
+ "vscode": {
+ "extensions": [
+ "ms-vscode.cpptools",
+ "platformio.platformio-ide"
+ ]
+ }
+ },
+
+ // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
+ // "remoteUser": "root"
+
+ // Allow uploading to device
+ "mounts": ["type=bind,source=/dev/bus/usb,target=/dev/bus/usb"],
+ "runArgs": ["--privileged"]
+}
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..f33a02cd
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,12 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for more information:
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+# https://containers.dev/guide/dependabot
+
+version: 2
+updates:
+ - package-ecosystem: "devcontainers"
+ directory: "/"
+ schedule:
+ interval: weekly
diff --git a/platformio_override-template.ini b/platformio_override-template.ini
index c3791ae8..97f2fbf0 100644
--- a/platformio_override-template.ini
+++ b/platformio_override-template.ini
@@ -22,7 +22,7 @@ build_flags =
;region -- Default Build Environments : Used when Build All ---
extra_default_envs =
- ; Uncomment specific environments or create extra:
+ ; Uncomment specific environments or create extra (copy names from square brackets in user_setups/*/*.ini):
; az-touch-mod-esp32_ili9341_4MB
; az-touch-mod-esp32_ili9341_8MB
; d1-mini-esp32_ili9341
@@ -64,6 +64,9 @@ extra_default_envs =
; makerfabs-tft35-cap_4MB
; makerfabs-tft-s2_ili9488
; nodemcu32s-raspi
+ ; panlee-zw3d95ce01s-ar-4848_16MB
+ ; panlee-zw3d95ce01s-tr-4848_16MB
+ ; panlee-zw3d95ce01s-ur-4848_16MB
; s2-mini-esp32s2_ili9341
; ttgo_esp32_poe-ili9341
; lilygo-lily-pi_ili9481
From be7eba0191f94fd1420d0cb7d778e7b9ea11791c Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 19 Aug 2024 18:49:58 +0200
Subject: [PATCH 062/142] Downgrade acejs to 1.35.3 #783
---
data/edit.htm | 2 +-
data/script.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/edit.htm b/data/edit.htm
index c0a35dc2..1a112286 100644
--- a/data/edit.htm
+++ b/data/edit.htm
@@ -1 +1 @@
-openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
+openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
diff --git a/data/script.js b/data/script.js
index afd735c2..93a1d96d 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1 @@
-var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.35.4")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
+var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.35.3")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
From e6eae8b39180ab6d5bec53fade06fdecda84d104 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 22 Aug 2024 14:29:40 +0200
Subject: [PATCH 063/142] Add retain flag to mqtt_send_state #781
---
src/mqtt/hasp_mqtt.h | 2 +-
src/mqtt/hasp_mqtt_esp.cpp | 4 ++--
src/mqtt/hasp_mqtt_paho_async.cpp | 4 ++--
src/mqtt/hasp_mqtt_paho_single.cpp | 4 ++--
src/mqtt/hasp_mqtt_pubsubclient.cpp | 4 ++--
5 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/mqtt/hasp_mqtt.h b/src/mqtt/hasp_mqtt.h
index 89ced6c1..5aba7497 100644
--- a/src/mqtt/hasp_mqtt.h
+++ b/src/mqtt/hasp_mqtt.h
@@ -24,7 +24,7 @@ void mqttStart();
void mqttStop();
// int mqtt_send_object_state(uint8_t pageid, uint8_t btnid, const char* payload);
-int mqtt_send_state(const char* subtopic, const char* payload);
+int mqtt_send_state(const char* subtopic, const char* payload, bool retain=false);
int mqtt_send_discovery(const char* payload, size_t len);
int mqttPublish(const char* topic, const char* payload, size_t len, bool retain);
diff --git a/src/mqtt/hasp_mqtt_esp.cpp b/src/mqtt/hasp_mqtt_esp.cpp
index 8864c107..f19f3c5d 100644
--- a/src/mqtt/hasp_mqtt_esp.cpp
+++ b/src/mqtt/hasp_mqtt_esp.cpp
@@ -165,7 +165,7 @@ bool mqtt_send_lwt(bool online)
// return mqttPublish(tmp_topic, payload, false);
// }
-int mqtt_send_state(const char* subtopic, const char* payload)
+int mqtt_send_state(const char* subtopic, const char* payload, bool retain)
{
String tmp_topic((char*)0);
tmp_topic.reserve(128);
@@ -174,7 +174,7 @@ int mqtt_send_state(const char* subtopic, const char* payload)
// tmp_topic += "/";
tmp_topic += subtopic;
- return mqttPublish(tmp_topic.c_str(), payload, false);
+ return mqttPublish(tmp_topic.c_str(), payload, retain);
}
int mqtt_send_discovery(const char* payload, size_t len)
diff --git a/src/mqtt/hasp_mqtt_paho_async.cpp b/src/mqtt/hasp_mqtt_paho_async.cpp
index 28b81d10..a75bb699 100644
--- a/src/mqtt/hasp_mqtt_paho_async.cpp
+++ b/src/mqtt/hasp_mqtt_paho_async.cpp
@@ -284,11 +284,11 @@ bool mqttIsConnected()
return mqttConnected; // MQTTAsync_isConnected(mqtt_client); // <- deadlocking on Linux
}
-int mqtt_send_state(const __FlashStringHelper* subtopic, const char* payload)
+int mqtt_send_state(const __FlashStringHelper* subtopic, const char* payload, bool retain)
{
char tmp_topic[mqttNodeTopic.length() + 20];
snprintf_P(tmp_topic, sizeof(tmp_topic), ("%s" MQTT_TOPIC_STATE "/%s"), mqttNodeTopic.c_str(), subtopic);
- return mqttPublish(tmp_topic, payload, strlen(payload), false);
+ return mqttPublish(tmp_topic, payload, strlen(payload), retain);
}
int mqtt_send_discovery(const char* payload, size_t len)
diff --git a/src/mqtt/hasp_mqtt_paho_single.cpp b/src/mqtt/hasp_mqtt_paho_single.cpp
index 50044044..2d1565b3 100644
--- a/src/mqtt/hasp_mqtt_paho_single.cpp
+++ b/src/mqtt/hasp_mqtt_paho_single.cpp
@@ -226,11 +226,11 @@ bool mqttIsConnected()
return MQTTClient_isConnected(mqtt_client);
}
-int mqtt_send_state(const __FlashStringHelper* subtopic, const char* payload)
+int mqtt_send_state(const __FlashStringHelper* subtopic, const char* payload, bool retain)
{
char tmp_topic[mqttNodeTopic.length() + 20];
snprintf_P(tmp_topic, sizeof(tmp_topic), ("%s" MQTT_TOPIC_STATE "/%s"), mqttNodeTopic.c_str(), subtopic);
- return mqttPublish(tmp_topic, payload, strlen(payload), false);
+ return mqttPublish(tmp_topic, payload, strlen(payload), retain);
}
int mqtt_send_discovery(const char* payload, size_t len)
diff --git a/src/mqtt/hasp_mqtt_pubsubclient.cpp b/src/mqtt/hasp_mqtt_pubsubclient.cpp
index 9acd5ce8..84e2a2b5 100644
--- a/src/mqtt/hasp_mqtt_pubsubclient.cpp
+++ b/src/mqtt/hasp_mqtt_pubsubclient.cpp
@@ -117,11 +117,11 @@ bool mqtt_send_lwt(bool online)
// return mqttPublish(tmp_topic, payload, false);
// }
-int mqtt_send_state(const char* subtopic, const char* payload)
+int mqtt_send_state(const char* subtopic, const char* payload, bool retain)
{
char tmp_topic[strlen(mqttNodeTopic) + strlen(subtopic) + 16];
snprintf_P(tmp_topic, sizeof(tmp_topic), PSTR("%s" MQTT_TOPIC_STATE "/%s"), mqttNodeTopic, subtopic);
- return mqttPublish(tmp_topic, payload, false);
+ return mqttPublish(tmp_topic, payload, retain);
}
int mqtt_send_discovery(const char* payload, size_t len)
From ca346e868f8b97fd409751aecc47162850bd8955 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Sat, 24 Aug 2024 20:00:05 +0200
Subject: [PATCH 064/142] Fix anti-burn when software rotation is enabled #764
---
src/hasp/hasp.cpp | 41 ++++++++++++++++++++++++++---------------
1 file changed, 26 insertions(+), 15 deletions(-)
diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp
index 35388570..4e0f4eef 100644
--- a/src/hasp/hasp.cpp
+++ b/src/hasp/hasp.cpp
@@ -217,11 +217,12 @@ void hasp_antiburn_cb(lv_task_t* task)
lv_obj_t* layer = lv_disp_get_layer_sys(NULL);
if(layer) {
// Fill a buffer with random colors
- lv_color_t color[1223];
- size_t len = sizeof(color) / sizeof(color[0]);
- for(size_t x = 0; x < len; x++) {
+ lv_color_t color[1223]; // prime
+ size_t max_len = sizeof(color) / sizeof(color[0]);
+ for(size_t x = 0; x < max_len; x++) {
color[x].full = HASP_RANDOM(UINT16_MAX);
}
+ max_len -= 64; // leave some headroom to randomize
// list of possible draw widths; prime numbers combat recurring patterns on the screen
uint8_t prime[] = {61, 67, 73, 79, 83, 89, 97, 103, 109, 113, 127, 131, 137, 139, 149,
@@ -230,17 +231,27 @@ void hasp_antiburn_cb(lv_task_t* task)
lv_disp_t* disp = lv_disp_get_default();
lv_disp_drv_t* disp_drv = &disp->driver;
- lv_coord_t scr_h = lv_obj_get_height(layer) - 1;
- lv_coord_t scr_w = lv_obj_get_width(layer) - 1;
- lv_coord_t w = 487; // first prime larger than 480
+ lv_coord_t scr_h;
+ lv_coord_t scr_w;
+
+ if(disp_drv->sw_rotate) {
+ scr_w = disp_drv->hor_res - 1; // use hardware w
+ scr_h = disp_drv->ver_res - 1; // use hardware h
+ } else {
+ scr_w = lv_obj_get_width(layer) - 1; // use software w
+ scr_h = lv_obj_get_height(layer) - 1; // use software h
+ }
+
+ lv_coord_t w = scr_w; // maximum screen width
lv_area_t area;
area.y1 = 0;
while(area.y1 <= scr_h) {
- if(w > scr_w) w = scr_w; // limit to the actual screenwidth
- if(w > len) w = len; // don't overrun the buffer
- lv_coord_t h = len / w;
- size_t headroom = len % w; // additional bytes in the buffer that can be used for a random offset
+ if(w > scr_w) w = scr_w; // limit to the actual screenwidth
+ if(w > max_len) w = max_len; // don't overrun the buffer
+ lv_coord_t h = max_len / w;
+ size_t headroom = (sizeof(color) / sizeof(color[0])) -
+ (h * w); // additional bytes in the buffer that can be used for a random offset
area.y2 = area.y1 + h - 1;
if(area.y2 > scr_h) area.y2 = scr_h;
@@ -255,16 +266,16 @@ void hasp_antiburn_cb(lv_task_t* task)
area.x1 += w;
}
- w = prime[HASP_RANDOM(sizeof(prime))]; // new random width
+ w = prime[HASP_RANDOM(sizeof(prime) / sizeof(prime[0]))]; // new random width
area.y1 += h;
}
}
- if(task->repeat_count != 1) return; // don't stop yet
-
// task is about to get deleted
- hasp_stop_antiburn();
- dispatch_state_antiburn(HASP_EVENT_OFF);
+ if(task->repeat_count == 1) {
+ hasp_stop_antiburn();
+ dispatch_state_antiburn(HASP_EVENT_OFF);
+ }
}
/**
From 401a134658bb55a374ff51f32e97a3c596ff5193 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 26 Aug 2024 01:21:10 +0200
Subject: [PATCH 065/142] Add minifests to build step
---
.github/workflows/build.yaml | 2 +-
platformio.ini | 2 +-
tools/esp_merge_bin.py | 51 ++++++++++++++++++++++++++++++++++--
3 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 64838bd1..ec5fbb22 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -101,7 +101,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.environment.out }}
- path: build_output/firmware/*.bin
+ path: build_output/firmware/*.*n
- name: Create release and upload firmware
if: github.ref != 'refs/heads/master'
run: |
diff --git a/platformio.ini b/platformio.ini
index a003dc93..90ddcee9 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -75,7 +75,7 @@ build_flags =
-D HASP_VER_MAJ=0
-D HASP_VER_MIN=7
;-D HASP_VER_REV=4
- -D HASP_VER_REV=0-rc12
+ -D HASP_VER_REV=0-rc13
;-D HASP_VER_REV=4-rc1
${override.build_flags}
diff --git a/tools/esp_merge_bin.py b/tools/esp_merge_bin.py
index 4c484f78..520f6c66 100644
--- a/tools/esp_merge_bin.py
+++ b/tools/esp_merge_bin.py
@@ -1,6 +1,5 @@
Import('env')
-import os
-import sys
+import os, sys, json
import shutil
import subprocess
import pkg_resources
@@ -106,6 +105,53 @@ def copy_merge_bins(source, target, env):
print(stdout.decode("utf-8") )
print(stderr.decode("utf-8") )
+def create_manifest(source, target, env):
+ short_version = 'v' + str(HASP_VER_MAJ) + '.' + str(HASP_VER_MIN) + '.' + str(HASP_VER_REV)
+ long_version = short_version + '_' + get_firmware_commit_hash()
+ name = str(target[0]).split(os.path.sep)[2]
+ name = name.replace('_4MB', '').replace('_8MB', '').replace('_16MB', '').replace('_32MB', '')
+ flash_size = env.GetProjectOption("board_upload.flash_size")
+ board = env.BoardConfig()
+ filename = "{}_full_{}_{}.json".format(name, flash_size, long_version)
+ output_json ="{}firmware{}{}".format(OUTPUT_DIR, os.path.sep, filename)
+
+ data = {"name":"openHASP", "version": short_version, "home_assistant_domain": "openhasp", "funding_url": "https://ko-fi.com/openhasp", "new_install_prompt_erase": True, "builds": "d"}
+ builds = []
+ parts = []
+ parts.append({ "path": filename, "offset": 0 })
+
+ mcu = board.get("build.mcu", "esp32")
+ if (mcu == 'esp32'):
+ builds.append({ "chipFamily": "ESP32", "improv": False })
+ elif (mcu == 'esp32s2'):
+ builds.append({ "chipFamily": "ESP32-S2", "improv": False })
+ elif (mcu == 'esp32s3'):
+ builds.append({ "chipFamily": "ESP32-S3", "improv": False })
+ elif (mcu == 'esp32c3'):
+ builds.append({ "chipFamily": "ESP32-C3", "improv": False })
+ elif (mcu == 'esp32c6'):
+ builds.append({ "chipFamily": "ESP32-C6", "improv": False })
+ builds[0]["parts"] = parts
+ data["builds"] = builds
+ json_data = json.dumps(data, indent=4, sort_keys=False)
+ print(json_data)
+
+ # check if output directories exist and create if necessary
+ if not os.path.isdir(OUTPUT_DIR):
+ os.mkdir(OUTPUT_DIR)
+
+ for d in ['firmware', 'map']:
+ if not os.path.isdir("{}{}".format(OUTPUT_DIR, d)):
+ os.mkdir("{}{}".format(OUTPUT_DIR, d))
+
+ # check if new target files exist and remove if necessary
+ for f in [output_json]:
+ if os.path.isfile(f):
+ os.remove(f)
+
+ with open(output_json, "w") as outfile:
+ outfile.write(json_data)
+
def copy_ota(source, target, env):
version = 'v' + str(HASP_VER_MAJ) + '.' + str(HASP_VER_MIN) + '.' + str(HASP_VER_REV) + '_' + get_firmware_commit_hash()
name =str(target[0]).split(os.path.sep)[2]
@@ -135,4 +181,5 @@ def copy_ota(source, target, env):
env.AddPreAction("$BUILD_DIR/${PROGNAME}.bin", [get_fw_version])
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [copy_merge_bins])
+env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [create_manifest])
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [copy_ota])
From 962b01d91f2a36c0bb21eb5d16307861ccce4aae Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 26 Aug 2024 01:49:45 +0200
Subject: [PATCH 066/142] Update build.yaml
---
.github/workflows/build.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index ec5fbb22..d97220fb 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -2,7 +2,7 @@ name: Build branch
on:
release:
- types: [created]
+ types: [published]
push:
branches:
- master
From d6f3b52911503595f4dd351b2d9deae0c10057dc Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 26 Aug 2024 02:05:57 +0200
Subject: [PATCH 067/142] Update asset upload on release
---
.github/workflows/build.yaml | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index d97220fb..52687e45 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -103,17 +103,22 @@ jobs:
name: ${{ matrix.environment.out }}
path: build_output/firmware/*.*n
- name: Create release and upload firmware
- if: github.ref != 'refs/heads/master'
- run: |
- set -x
- assets=()
- for asset in build_output/firmware/*.bin; do
- assets+=("-a" "$asset")
- done
- tag_name="${GITHUB_REF##*/}"
- hub release edit "${assets[@]}" -m "$tag_name" "$tag_name"
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ uses: AButler/upload-release-assets@v3.0
+ with:
+ files: "build_output/firmware/*.bin"
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
+ # - name: Create release and upload firmware
+ # if: github.ref != 'refs/heads/master'
+ # run: |
+ # set -x
+ # assets=()
+ # for asset in build_output/firmware/*.bin; do
+ # assets+=("-a" "$asset")
+ # done
+ # tag_name="${GITHUB_REF##*/}"
+ # hub release edit "${assets[@]}" -m "$tag_name" "$tag_name"
+ # env:
+ # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
#- name: Create release and upload firmware
# run: |
# set -x
From 1f01ece609266e08a2686454dfa89d6f1b2ed44c Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 26 Aug 2024 02:12:32 +0200
Subject: [PATCH 068/142] Update release workflow
---
.github/workflows/build.yaml | 27 +++------------------------
1 file changed, 3 insertions(+), 24 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 52687e45..de28675d 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -102,34 +102,13 @@ jobs:
with:
name: ${{ matrix.environment.out }}
path: build_output/firmware/*.*n
- - name: Create release and upload firmware
+ - name: On Release, upload assets to that Release
uses: AButler/upload-release-assets@v3.0
with:
files: "build_output/firmware/*.bin"
repo-token: ${{ secrets.GITHUB_TOKEN }}
- # - name: Create release and upload firmware
- # if: github.ref != 'refs/heads/master'
- # run: |
- # set -x
- # assets=()
- # for asset in build_output/firmware/*.bin; do
- # assets+=("-a" "$asset")
- # done
- # tag_name="${GITHUB_REF##*/}"
- # hub release edit "${assets[@]}" -m "$tag_name" "$tag_name"
- # env:
- # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- #- name: Create release and upload firmware
- # run: |
- # set -x
- # assets=()
- # for asset in build_output/firmware/*.bin; do
- # assets+=("-a" "$asset")
- # done
- # tag_name="${GITHUB_REF##*/}"
- # hub release create "${assets[@]}" -m "$tag_name" "$tag_name"
- # env:
- # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+
linux_build:
runs-on: ubuntu-latest
steps:
From 4e1663979401c5809a6754bdc054a10229c052e2 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 26 Aug 2024 02:22:51 +0200
Subject: [PATCH 069/142] Zip atrifacts before release upload
---
.github/workflows/build.yaml | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index de28675d..6a6bf8a1 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -102,13 +102,16 @@ jobs:
with:
name: ${{ matrix.environment.out }}
path: build_output/firmware/*.*n
+ ## Release only:
+ - name: Zip artifact for deployment
+ run: zip ${{ matrix.environment.out }}.zip "build_output/firmware/*.bin" -r
- name: On Release, upload assets to that Release
uses: AButler/upload-release-assets@v3.0
with:
- files: "build_output/firmware/*.bin"
+ files: ${{ matrix.environment.out }}.zip
repo-token: ${{ secrets.GITHUB_TOKEN }}
-
+
linux_build:
runs-on: ubuntu-latest
steps:
From 7053024146a669f249b9525241ef4f3eabf3d6ed Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 26 Aug 2024 02:27:33 +0200
Subject: [PATCH 070/142] Upload assets only on release
---
.github/workflows/build.yaml | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 6a6bf8a1..185e3ae5 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -104,8 +104,11 @@ jobs:
path: build_output/firmware/*.*n
## Release only:
- name: Zip artifact for deployment
- run: zip ${{ matrix.environment.out }}.zip "build_output/firmware/*.bin" -r
+ if: github.ref != 'refs/heads/master'
+ run: |
+ zip ${{ matrix.environment.out }}.zip "build_output/firmware/*.bin" -r
- name: On Release, upload assets to that Release
+ if: github.ref != 'refs/heads/master'
uses: AButler/upload-release-assets@v3.0
with:
files: ${{ matrix.environment.out }}.zip
From 042fe057254706f9ac04ae842a948fa3fd236606 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 26 Aug 2024 02:32:55 +0200
Subject: [PATCH 071/142] Update build.yaml zip step
---
.github/workflows/build.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 185e3ae5..2353593d 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -106,7 +106,7 @@ jobs:
- name: Zip artifact for deployment
if: github.ref != 'refs/heads/master'
run: |
- zip ${{ matrix.environment.out }}.zip "build_output/firmware/*.bin" -r
+ zip ${{ matrix.environment.out }}.zip build_output/firmware/*.bin -r
- name: On Release, upload assets to that Release
if: github.ref != 'refs/heads/master'
uses: AButler/upload-release-assets@v3.0
From 08dd9c5004bea92f4a0bf9c380763c5d7d81bc4c Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Mon, 26 Aug 2024 02:47:24 +0200
Subject: [PATCH 072/142] Obsolete workflows
---
.github/workflows/build_linux.yaml | 2 +-
.github/workflows/release.yml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/build_linux.yaml b/.github/workflows/build_linux.yaml
index cd92d6be..5d081c18 100644
--- a/.github/workflows/build_linux.yaml
+++ b/.github/workflows/build_linux.yaml
@@ -1,4 +1,4 @@
-name: Build branch
+name: Build Linux (Obsolete)
on:
workflow_dispatch:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index ed1ce258..7464a8e3 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -3,7 +3,7 @@ on:
# types: [created]
workflow_dispatch:
-name: Create Release
+name: Create Release (Obsolete)
jobs:
build:
From 825f5c6da582596785ff919bc686174a478a2a73 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Tue, 27 Aug 2024 23:44:50 +0200
Subject: [PATCH 073/142] New translations en.json (Spanish)
---
data/es_ES.json | 46 +++++++++++++++++++++++-----------------------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/data/es_ES.json b/data/es_ES.json
index 7df5c933..2bacf1cd 100644
--- a/data/es_ES.json
+++ b/data/es_ES.json
@@ -15,18 +15,18 @@
"theme": "Tema de IU",
"color1": "Color Primario",
"color2": "Color Secundario",
- "pages": "Diseño inicial",
+ "pages": "Diseño Inicial",
"font": "Fuente por Defecto",
- "startpage": "Página inicial",
- "startdim": "Brillo inicial"
+ "startpage": "Página de Inicio",
+ "startdim": "Brillo Inicial"
},
"screenshot": {
- "title": "Captura de pantalla",
- "btn": "Captura de pantalla",
- "nav": "Captura de pantalla",
- "prev": "Página Previa",
+ "title": "Captura de Pantalla",
+ "btn": "Captura de Pantalla",
+ "nav": "Captura de Pantalla",
+ "prev": "Prev Página",
"next": "Siguiente Página",
- "refresh": "Refrescar"
+ "refresh": "Actualizar"
},
"info": {
"title": "Información",
@@ -36,16 +36,16 @@
"config": {
"title": "Configuración",
"btn": "Configuración",
- "nav": "Configuración"
+ "nav": "Configuraciones"
},
"ota": {
- "title": "Actualización de firmware",
- "btn": "Actualización de firmware",
+ "title": "Actualización de Firmware",
+ "btn": "Actualización de Firmware",
"nav": "Firmware",
"submit": "Actualizar Firmware",
"file": "Archivo Firmware",
- "url": "URL del firmware",
- "redirect": "Seguir redirecciones",
+ "url": "URL del Firmware",
+ "redirect": "Sigue Redirecciones",
"never": "Nunca",
"strict": "Estricto",
"always": "Siempre"
@@ -56,10 +56,10 @@
"nav": "Editor de Archivos"
},
"reset": {
- "title": "Restaurar conf de fábrica",
- "btn": "Restaurar conf de fábrica",
+ "title": "Reconfiguración de Fábrica",
+ "btn": "Restaurar conf de Fábrica",
"warning": "Aviso",
- "message": "Este proceso restablecerá todos los ajustes a los valores por defecto. El flash interno se borrará y el dispositivo se reiniciará. Puede que necesite conectarse al AP WiFi mostrado en el panel para reconfigurar el dispositivo antes de volver a acceder a él.",
+ "message": "Este proceso restablecerá todos los ajustes a los valores predeterminados. El flash interno se borrará y el dispositivo se reiniciará. Es posible que necesite conectarse al AP WiFi mostrado en el panel para reconfigurar el dispositivo antes de volver a acceder a él.",
"fileloss": "¡TODOS LOS ARCHIVOS SERÁN PERDIDOS!"
},
"reboot": {
@@ -124,9 +124,9 @@
},
"gpio": "Ajustes GPIO",
"debug": {
- "title": "Ajustes de depuración",
- "btn": "Ajustes de depuración",
- "baud": "Baudios",
+ "title": "Ajustes de Depuración",
+ "btn": "Ajustes de Depuración",
+ "baud": "Tasa Baudios",
"tele": "Periodo de Tele",
"ansi": "Usar códigos ANSI",
"host": "Servidor Syslog",
@@ -139,9 +139,9 @@
"title": "Ajustes de Tiempo",
"btn": "Ajustes de Tiempo",
"region": "Región",
- "zone": "Zona horaria",
- "tz": "Zona horaria",
- "ntp": "Servidores NTP"
+ "zone": "Zona Horaria",
+ "tz": "Zona Horaria",
+ "ntp": "Servidor NTP"
},
"region": {
"etc": "Etcetera ",
@@ -149,7 +149,7 @@
"af": "Africa ",
"as": "Asia ",
"au": "Australia ",
- "aq": "Antarctica ",
+ "aq": "Antártida",
"eu": "Europa ",
"na": "América del Norte ",
"sa": "América del Sur ",
From e799a01bc522143b74f558357ffe89611a9a93af Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Tue, 27 Aug 2024 23:44:51 +0200
Subject: [PATCH 074/142] New translations en.json (Swedish)
---
data/sv_SE.json | 162 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 162 insertions(+)
create mode 100644 data/sv_SE.json
diff --git a/data/sv_SE.json b/data/sv_SE.json
new file mode 100644
index 00000000..fc90532d
--- /dev/null
+++ b/data/sv_SE.json
@@ -0,0 +1,162 @@
+{
+ "en": {
+ "language": "Svenska",
+ "home": {
+ "title": "Huvudmeny",
+ "btn": "Huvudmeny",
+ "nav": "Home"
+ },
+ "save": "Spara Inställningar",
+ "user": "Username",
+ "pass": "Password",
+ "hasp": {
+ "title": "HASP Design",
+ "btn": "HASP Design",
+ "theme": "UI Theme",
+ "color1": "Primary color",
+ "color2": "Secondary color",
+ "pages": "Start Layout",
+ "font": "Default Font",
+ "startpage": "Startup Page",
+ "startdim": "Startup Dim"
+ },
+ "screenshot": {
+ "title": "Screenshot",
+ "btn": "Screenshot",
+ "nav": "Screenshot",
+ "prev": "Prev Page",
+ "next": "Next Page",
+ "refresh": "Refresh"
+ },
+ "info": {
+ "title": "Information",
+ "btn": "Information",
+ "nav": "Information"
+ },
+ "config": {
+ "title": "Configuration",
+ "btn": "Configuration",
+ "nav": "Settings"
+ },
+ "ota": {
+ "title": "Firmware Update",
+ "btn": "Firmware Update",
+ "nav": "Firmware",
+ "submit": "Update Firmware",
+ "file": "Firmware File",
+ "url": "Firmware URL",
+ "redirect": "Follow Redirects",
+ "never": "Never",
+ "strict": "Strict",
+ "always": "Always"
+ },
+ "editor": {
+ "title": "File Editor",
+ "btn": "File Editor",
+ "nav": "File Editor"
+ },
+ "reset": {
+ "title": "Factory Reset",
+ "btn": "Factory Reset",
+ "warning": "Warning",
+ "message": "This process will reset all settings to the default values. The internal flash will be erased and the device is restarted. You may need to connect to the WiFi AP displayed on the panel to reconfigure the device before accessing it again.",
+ "fileloss": "ALL FILES WILL BE LOST!"
+ },
+ "reboot": {
+ "title": "Rebooting...",
+ "btn": "Restart",
+ "nav": "Reboot",
+ "message": "The device is rebooting."
+ },
+ "about": {
+ "credits": "Based on the previous work of the following open source developers:",
+ "copyright": "Copyright ",
+ "rights": "All rights reserved.",
+ "clause1": "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:",
+ "clause2": "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.",
+ "clause3": "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
+ "mit": "MIT License",
+ "bsd": "BSD License",
+ "freebsd": "FreeBSD License",
+ "apache2": "Apache2 License"
+ },
+ "wifi": {
+ "title": "Wifi Settings",
+ "btn": "Wifi Settings",
+ "ssid": "SSID"
+ },
+ "wg": {
+ "title": "WireGuard Settings",
+ "btn": "WireGuard Settings",
+ "vpnip": "VPN IP",
+ "privkey": "Private Key",
+ "host": "Remote IP",
+ "port": "Remote Port",
+ "pubkey": "Remote Public Key"
+ },
+ "mqtt": {
+ "title": "MQTT Settings",
+ "btn": "MQTT Settings",
+ "name": "Hostname",
+ "group": "Groupname",
+ "host": "Broker",
+ "port": "Port",
+ "node_t": "Node Topic",
+ "group_t": "Group Topic",
+ "broadcast_t": "Broadcast Topic",
+ "hass_t": "HA LWT Topic"
+ },
+ "http": {
+ "title": "HTTP Settings",
+ "btn": "HTTP Settings"
+ },
+ "ftp": {
+ "title": "FTP Settings",
+ "btn": "FTP Settings",
+ "port": "FTP Port",
+ "pasv": "Passive Port"
+ },
+ "gui": {
+ "title": "Display Settings",
+ "btn": "Display Settings",
+ "antiburn": "Antiburn",
+ "calibrate": "Calibrate"
+ },
+ "gpio": "GPIO Settings",
+ "debug": {
+ "title": "Debug Settings",
+ "btn": "Debug Settings",
+ "baud": "Baudrate",
+ "tele": "Tele Period",
+ "ansi": "Use ANSI codes",
+ "host": "Syslog Server",
+ "port": "Syslog Port",
+ "ietf": "IETF (RFC 5424)",
+ "bsd": "BSD (RFC 3164)",
+ "log": "Facility"
+ },
+ "time": {
+ "title": "Time Settings",
+ "btn": "Time Settings",
+ "region": "Region",
+ "zone": "Timezone",
+ "tz": "Timezone",
+ "ntp": "NTP Servers"
+ },
+ "region": {
+ "etc": "Etcetera ",
+ "continents": "Continents ",
+ "af": "Africa ",
+ "as": "Asia ",
+ "au": "Australia ",
+ "aq": "Antarctica ",
+ "eu": "Europe ",
+ "na": "North America ",
+ "sa": "South America ",
+ "islands": "Islands ",
+ "at": "Atlantic Ocean ",
+ "in": "Indian Ocean ",
+ "pa": "Pacific Ocean "
+ }
+ }
+}
\ No newline at end of file
From 5cbb92d6176f1ce490d31fdc56db84ad3387a090 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Tue, 27 Aug 2024 23:44:52 +0200
Subject: [PATCH 075/142] New translations en_us.h (Swedish)
---
src/lang/sv_SE.h | 242 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 242 insertions(+)
create mode 100644 src/lang/sv_SE.h
diff --git a/src/lang/sv_SE.h b/src/lang/sv_SE.h
new file mode 100644
index 00000000..334ce96e
--- /dev/null
+++ b/src/lang/sv_SE.h
@@ -0,0 +1,242 @@
+// This translation file is maintained on https://crowdin.com/project/openhasp/
+// Do not edit directly!
+
+#ifndef HASP_LANG_SV_SE_H
+#define HASP_LANG_SV_SE_H
+
+#define D_ISO_LANG_CODE "sv-SE"
+
+#define D_USERNAME "Användarnamn:"
+#define D_PASSWORD "Lösenord:"
+#define D_SSID "Ssid:"
+#define D_YES "Ja"
+#define D_NO "Nej"
+
+#define D_ERROR_OUT_OF_MEMORY "Out of memory"
+#define D_ERROR_UNKNOWN "Unknown error"
+
+#define D_CONFIG_NOT_CHANGED "Settings did not change"
+#define D_CONFIG_CHANGED "Settings changed"
+#define D_CONFIG_LOADED "Settings loaded"
+
+#define D_FILE_LOADING "Loading %s"
+#define D_FILE_LOADED "Loaded %s"
+#define D_FILE_LOAD_FAILED "Failed to load %s"
+#define D_FILE_SAVING "Saving %s"
+#define D_FILE_SAVED "Saved %s"
+#define D_FILE_SAVE_FAILED "Failed to save %s"
+#define D_FILE_NOT_FOUND "File not found"
+#define D_FILE_SIZE_BYTES "bytes"
+#define D_FILE_SIZE_KILOBYTES "KiB"
+#define D_FILE_SIZE_MEGABYTES "MiB"
+#define D_FILE_SIZE_GIGABYTES "GiB"
+#define D_FILE_SIZE_TERABYTES "TiB"
+#define D_FILE_SIZE_DIVIDER 1024 // kibi or kilo bytes
+#define D_DECIMAL_POINT "." // decimal comma or point
+
+#define D_SERVICE_STARTING "Starting..."
+#define D_SERVICE_STARTED "Started"
+#define D_SERVICE_START_FAILED "Failed to start"
+#define D_SERVICE_STOPPED "Stopped"
+#define D_SERVICE_DISABLED "Disabled"
+#define D_SERVICE_CONNECTED "Connected"
+#define D_SERVICE_DISCONNECTED "Disconnected"
+
+#define D_SETTING_ENABLED "Enabled"
+#define D_SETTING_DISABLED "Disabled"
+#define D_SETTING_DEFAULT "Default"
+
+#define D_NETWORK_IP_ADDRESS_RECEIVED "Received IP address %s"
+#define D_NETWORK_ONLINE "online"
+#define D_NETWORK_OFFLINE "offline"
+#define D_NETWORK_CONNECTION_FAILED "Connection failed"
+#define D_NETWORK_CONNECTION_UNAUTHORIZED "Authorization failed"
+
+#define D_MQTT_DEFAULT_NAME "plate_%s"
+#define D_MQTT_CONNECTING "Connecting..."
+#define D_MQTT_CONNECTED "Connected to broker %s as clientID %s"
+#define D_MQTT_NOT_CONNECTED "Not connected ???"
+#define D_MQTT_DISCONNECTING "Disconnecting..."
+#define D_MQTT_DISCONNECTED "Disconnected"
+#define D_MQTT_RECONNECTING "Disconnected from broker, reconnection..."
+#define D_MQTT_NOT_CONFIGURED "Broker not configured"
+#define D_MQTT_STARTED "Started: %d bytes"
+#define D_MQTT_FAILED "Failed:"
+#define D_MQTT_INVALID_TOPIC "Message has invalid topic"
+#define D_MQTT_SUBSCRIBED "Subscribed to %s"
+#define D_MQTT_NOT_SUBSCRIBED "Failed to subscribe to %s"
+#define D_MQTT_HA_AUTO_DISCOVERY "Register HA auto-discovery"
+#define D_MQTT_PAYLOAD_TOO_LONG "Payload too long (%u bytes)"
+
+#define D_TELNET_CLOSING_CONNECTION "Closing session from %s"
+#define D_TELNET_CLIENT_LOGIN_FROM "Client login from %s"
+#define D_TELNET_CLIENT_CONNECT_FROM "Client connected from %s"
+#define D_TELNET_CLIENT_NOT_CONNECTED "Client NOT connected"
+#define D_TELNET_INCORRECT_LOGIN_ATTEMPT "Incorrect login attempt from %s"
+#define D_TELNET_STARTED "Telnet console started"
+#define D_TELNET_FAILED "Failed to start telnet console"
+#define D_TELNET_CLIENT_CONNECTED "Client connected"
+#define D_TELNET_CLIENT_REJECTED "Client rejected"
+
+#define D_HASP_INVALID_PAGE "Invalid page %u"
+#define D_HASP_INVALID_LAYER "Cannot clear system layer"
+#define D_HASP_CHANGE_PAGE "Changing page to %u"
+#define D_HASP_CLEAR_PAGE "Clearing page %u"
+
+#define D_OBJECT_DELETED "Object deleted"
+#define D_OBJECT_UNKNOWN "Unknown object"
+#define D_OBJECT_MISMATCH "Objects DO NOT match!"
+#define D_OBJECT_LOST "Lost object!"
+#define D_OBJECT_CREATE_FAILED "Failed to create object id %u"
+#define D_OBJECT_PAGE_UNKNOWN "Page ID %u not defined"
+#define D_OBJECT_EVENT_UNKNOWN "Unknown Event %d"
+
+#define D_ATTRIBUTE_UNKNOWN "Unknown property %s"
+// D_ATTRIBUTE_OBSOLETE D_ATTRIBUTE_INSTEAD can be used together or just D_ATTRIBUTE_OBSOLETE alone
+#define D_ATTRIBUTE_OBSOLETE "%s is obsolete"
+#define D_ATTRIBUTE_INSTEAD ", use %s instead"
+#define D_ATTRIBUTE_READ_ONLY "%s is read-only"
+#define D_ATTRIBUTE_PAGE_METHOD_INVALID "Unable to call %s on a page"
+#define D_ATTRIBUTE_ALIGN_INVALID "Invalid align property: %s"
+#define D_ATTRIBUTE_COLOR_INVALID "Invalid color property: %s"
+#define D_ATTRIBUTE_LONG_MODE_INVALID "Invalid long mode: %s"
+
+#define D_OOBE_SSID_VALIDATED "SSID %s validated"
+#define D_OOBE_AUTO_CALIBRATE "Auto calibrate enabled"
+#define D_OOBE_CALIBRATED "Already calibrated"
+
+#define D_DISPATCH_COMMAND_NOT_FOUND "Command '%s' not found"
+#define D_DISPATCH_INVALID_PAGE "Invalid page %s"
+#define D_DISPATCH_REBOOT "Rebooting the MCU now!"
+
+#define D_JSON_FAILED "JSON parsing failed:"
+#define D_JSONL_FAILED "JSONL parsing failed at line %u"
+#define D_JSONL_SUCCEEDED "Jsonl fully parsed"
+
+#define D_OTA_CHECK_UPDATE "Trying update URL: %s"
+#define D_OTA_CHECK_COMPLETE "Update check complete"
+#define D_OTA_CHECK_FAILED "Update check failed: %s"
+#define D_OTA_UPDATE_FIRMWARE "OTA Firmware Update"
+#define D_OTA_UPDATE_COMPLETE "OTA Update complete"
+#define D_OTA_UPDATE_APPLY "Applying Firmware & Reboot"
+#define D_OTA_UPDATE_FAILED "OTA Update failed"
+#define D_OTA_UPDATING_FIRMWARE "Updating firmware..."
+#define D_OTA_UPDATING_FILESYSTEM "Updating filesystem..."
+
+#define D_HTTP_HASP_DESIGN "HASP Design"
+#define D_HTTP_INFORMATION "Information"
+#define D_HTTP_HTTP_SETTINGS "HTTP Settings"
+#define D_HTTP_FTP_SETTINGS "FTP Settings"
+#define D_HTTP_WIFI_SETTINGS "Wifi Settings"
+#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
+#define D_HTTP_MQTT_SETTINGS "MQTT Settings"
+#define D_HTTP_GPIO_SETTINGS "GPIO Settings"
+#define D_HTTP_MDNS_SETTINGS "mDNS Settings"
+#define D_HTTP_TELNET_SETTINGS "Telnet Settings"
+#define D_HTTP_DEBUG_SETTINGS "Debug Settings"
+#define D_HTTP_GUI_SETTINGS "Display Settings"
+#define D_HTTP_SAVE_SETTINGS "Save Settings"
+#define D_HTTP_UPLOAD_FILE "Upload File"
+#define D_HTTP_ERASE_DEVICE "Reset All Settings"
+#define D_HTTP_ADD_GPIO "Add New Pin"
+#define D_HTTP_BACK "Back"
+#define D_HTTP_REFRESH "Refresh"
+#define D_HTTP_PREV_PAGE "Prev Page"
+#define D_HTTP_NEXT_PAGE "Next Page"
+#define D_HTTP_CALIBRATE "Calibrate"
+#define D_HTTP_ANTIBURN "Run Anti Burn-in"
+#define D_HTTP_SCREENSHOT "Screenshot"
+#define D_HTTP_FILE_BROWSER "File Editor"
+#define D_HTTP_FIRMWARE_UPGRADE "Firmware Upgrade"
+#define D_HTTP_UPDATE_FIRMWARE "Update Firmware"
+#define D_HTTP_FACTORY_RESET "Factory Reset"
+#define D_HTTP_MAIN_MENU "Main Menu"
+#define D_HTTP_REBOOT "Restart"
+#define D_HTTP_CONFIGURATION "Configuration"
+#define D_HTTP_CONFIG_CHANGED \
+ "The configuration has changed, please click Restart to save changes to flash."
+#define D_HTTP_SENDING_PAGE "Sent %S page to %s"
+#define D_HTTP_FOOTER "by Francis Van Roie"
+
+#define D_INFO_VERSION "Version"
+#define D_INFO_BUILD_DATETIME "Build DateTime"
+#define D_INFO_ENVIRONMENT "Environment"
+#define D_INFO_UPTIME "Uptime"
+#define D_INFO_FREE_HEAP "Free Heap"
+#define D_INFO_FREE_BLOCK "Free Block"
+#define D_INFO_DEVICE_MEMORY "Device Memory"
+#define D_INFO_LVGL_MEMORY "LVGL Memory"
+#define D_INFO_TOTAL_MEMORY "Total"
+#define D_INFO_FREE_MEMORY "Free"
+#define D_INFO_FRAGMENTATION "Fragmentation"
+#define D_INFO_PSRAM_FREE "PSRam Free"
+#define D_INFO_PSRAM_SIZE "PSRam Size"
+#define D_INFO_FLASH_SIZE "Flash Size"
+#define D_INFO_SKETCH_USED "Program Size Used"
+#define D_INFO_SKETCH_FREE "Program Size Free"
+#define D_INFO_FS_SIZE "Filesystem Size"
+#define D_INFO_FS_USED "Filesystem Used"
+#define D_INFO_FS_FREE "Filesystem Free"
+#define D_INFO_MODULE "Module"
+#define D_INFO_MODEL "Model"
+#define D_INFO_FREQUENCY "Frequency"
+#define D_INFO_CORE_VERSION "Core Version"
+#define D_INFO_RESET_REASON "Reset Reason"
+#define D_INFO_STATUS "Status"
+#define D_INFO_SERVER "Server"
+#define D_INFO_USERNAME "Username"
+#define D_INFO_CLIENTID "Client ID"
+// #define D_INFO_CONNECTED "Connected"
+// #define D_INFO_DISCONNECTED "Disconnected"
+#define D_INFO_RECEIVED "Received"
+#define D_INFO_PUBLISHED "Published"
+#define D_INFO_FAILED "Failed"
+#define D_INFO_ETHERNET "Ethernet"
+#define D_INFO_WIFI "Wifi"
+#define D_INFO_WIREGUARD "WireGuard"
+#define D_INFO_LINK_SPEED "Link Speed"
+#define D_INFO_FULL_DUPLEX "Full Duplex"
+#define D_INFO_BSSID "BSSID"
+#define D_INFO_SSID "SSID"
+#define D_INFO_RSSI "Signal Strength"
+#define D_INFO_IP_ADDRESS "IP Address"
+#define D_INFO_MAC_ADDRESS "MAC Address"
+#define D_INFO_GATEWAY "Gateway"
+#define D_INFO_DNS_SERVER "DNS Server"
+#define D_INFO_ENDPOINT_IP "Endpoint IP"
+#define D_INFO_ENDPOINT_PORT "Endpoint Port"
+
+#define D_OOBE_MSG "Tap the screen to setup WiFi or connect to this Access Point:"
+#define D_OOBE_SCAN_TO_CONNECT "Scan to connect"
+
+#define D_WIFI_CONNECTING_TO "Connecting to %s"
+#define D_WIFI_CONNECTED_TO "Connected to %s, requesting IP..."
+#define D_WIFI_RSSI_EXCELLENT "Excellent"
+#define D_WIFI_RSSI_GOOD "Good"
+#define D_WIFI_RSSI_FAIR "Fair"
+#define D_WIFI_RSSI_WEAK "Weak"
+#define D_WIFI_RSSI_BAD "Very bad"
+
+#define D_WG_INITIALIZED "Initialized"
+#define D_WG_BAD_CONFIG "Missing or bad configuration"
+
+#define D_GPIO_SWITCH "Switch"
+#define D_GPIO_BUTTON "Push Button"
+#define D_GPIO_TOUCH "Capacitive Touch"
+#define D_GPIO_LED "Led"
+#define D_GPIO_LED_R "Mood Red"
+#define D_GPIO_LED_G "Mood Green"
+#define D_GPIO_LED_B "Mood Blue"
+#define D_GPIO_POWER_RELAY "Power Relay"
+#define D_GPIO_LIGHT_RELAY "Light Relay"
+#define D_GPIO_PWM "PWM"
+#define D_GPIO_DAC "DAC"
+#define D_GPIO_SERIAL_DIMMER "Serial Dimmer"
+#define D_GPIO_UNKNOWN "Unknown"
+#define D_GPIO_PIN "Pin"
+#define D_GPIO_GROUP "Group"
+#define D_GPIO_GROUP_NONE "None"
+#define D_GPIO_STATE_NORMAL "Normal"
+#define D_GPIO_STATE_INVERTED "Inverted"
+
+#endif
\ No newline at end of file
From 391401b3a3468ef398b73245d36d99ff7aa8ee6c Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Tue, 27 Aug 2024 23:55:05 +0200
Subject: [PATCH 076/142] New translations en.json (Spanish)
---
data/es_ES.json | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/data/es_ES.json b/data/es_ES.json
index 2bacf1cd..0906e404 100644
--- a/data/es_ES.json
+++ b/data/es_ES.json
@@ -81,8 +81,8 @@
"apache2": "Licencia Apache2"
},
"wifi": {
- "title": "Ajustes Wifi",
- "btn": "Ajustes Wifi",
+ "title": "Ajustes WiFi",
+ "btn": "Ajustes WiFi",
"ssid": "SSID"
},
"wg": {
@@ -97,7 +97,7 @@
"mqtt": {
"title": "Ajustes MQTT",
"btn": "Ajustes MQTT",
- "name": "Nombre de equipo",
+ "name": "Nombre del Host",
"group": "Nombre del Grupo",
"host": "Broker",
"port": "Puerto",
@@ -149,7 +149,7 @@
"af": "Africa ",
"as": "Asia ",
"au": "Australia ",
- "aq": "Antártida",
+ "aq": "Antártida ",
"eu": "Europa ",
"na": "América del Norte ",
"sa": "América del Sur ",
From 4b89d9ca521dcdf041aa113b9655ee170b95ad93 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 28 Aug 2024 01:45:49 +0200
Subject: [PATCH 077/142] New translations en.json (Swedish)
---
data/sv_SE.json | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/data/sv_SE.json b/data/sv_SE.json
index fc90532d..b3b3bb25 100644
--- a/data/sv_SE.json
+++ b/data/sv_SE.json
@@ -72,16 +72,16 @@
"credits": "Based on the previous work of the following open source developers:",
"copyright": "Copyright ",
"rights": "All rights reserved.",
- "clause1": "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:",
- "clause2": "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.",
- "clause3": "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
+ "clause1": "Härmed beviljas tillstånd, utan kostnad, till alla personer som erhåller en kopia av denna programvara och tillhörande dokumentationsfiler (\"Programvaran\"), att hantera Programvaran utan begränsningar, inklusive men inte begränsat till rätten att använda, kopiera, modifiera, sammanfoga, publicera, distribuera, underlicensiera och/eller sälja kopior av Programvaran, samt att tillåta personer till vilka Programvaran tillhandahålls att göra detsamma, under förutsättning av följande villkor:",
+ "clause2": "Ovanstående meddelande om upphovsrätt och detta tillståndsmeddelande ska inkluderas i alla kopior eller väsentliga delar av programvaran.",
+ "clause3": "PROGRAMVARAN TILLHANDAHÅLLS \"I BEFINTLIGT SKICK\", UTAN NÅGON SOM HELST GARANTI, VARE SIG UTTRYCKLIG ELLER UNDERFÖRSTÅDD, INKLUSIVE MEN INTE BEGRÄNSAT TILL GARANTIER OM SÄLJBARHET, LÄMPLIGHET FÖR ETT VISST ÄNDAMÅL OCH ICKE-INTRÅNG. UNDER INGA OMSTÄNDIGHETER SKALL FÖRFATTARNA ELLER UPPHOVSRÄTTSINNEHAVARNA VARA ANSVARIGA FÖR NÅGON TYP AV KRAV, SKADOR ELLER ANNAT ANSVAR, VARE SIG I KONTRAKT, SKADESTÅND ELLER ANNAT, SOM UPPSTÅR FRÅN, UR ELLER I SAMBAND MED PROGRAMVARAN ELLER ANVÄNDNINGEN ELLER ANDRA ÅTGÄRDER I SAMBAND MED PROGRAMVARAN.",
"mit": "MIT License",
- "bsd": "BSD License",
- "freebsd": "FreeBSD License",
- "apache2": "Apache2 License"
+ "bsd": "BSD Licens",
+ "freebsd": "FreeBSD Licens",
+ "apache2": "Apache2 Licens"
},
"wifi": {
- "title": "Wifi Settings",
+ "title": "Inställningar för WiFi",
"btn": "Wifi Settings",
"ssid": "SSID"
},
From 4d2aa8d8e0e7089f9b5759ac8f933310fe1764df Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 28 Aug 2024 01:45:50 +0200
Subject: [PATCH 078/142] New translations en_us.h (Swedish)
---
src/lang/sv_SE.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/lang/sv_SE.h b/src/lang/sv_SE.h
index 334ce96e..048cb6e6 100644
--- a/src/lang/sv_SE.h
+++ b/src/lang/sv_SE.h
@@ -50,7 +50,7 @@
#define D_NETWORK_ONLINE "online"
#define D_NETWORK_OFFLINE "offline"
#define D_NETWORK_CONNECTION_FAILED "Connection failed"
-#define D_NETWORK_CONNECTION_UNAUTHORIZED "Authorization failed"
+#define D_NETWORK_CONNECTION_UNAUTHORIZED "Auktorisering misslyckades"
#define D_MQTT_DEFAULT_NAME "plate_%s"
#define D_MQTT_CONNECTING "Connecting..."
@@ -115,7 +115,7 @@
#define D_OTA_CHECK_UPDATE "Trying update URL: %s"
#define D_OTA_CHECK_COMPLETE "Update check complete"
-#define D_OTA_CHECK_FAILED "Update check failed: %s"
+#define D_OTA_CHECK_FAILED "Uppdateringskontroll misslyckades: %s"
#define D_OTA_UPDATE_FIRMWARE "OTA Firmware Update"
#define D_OTA_UPDATE_COMPLETE "OTA Update complete"
#define D_OTA_UPDATE_APPLY "Applying Firmware & Reboot"
From 4809ac3915ace62c23a9f3747950e887b2257094 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 28 Aug 2024 09:53:27 +0200
Subject: [PATCH 079/142] New translations en.json (Swedish)
---
data/sv_SE.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/sv_SE.json b/data/sv_SE.json
index b3b3bb25..d4a3dacd 100644
--- a/data/sv_SE.json
+++ b/data/sv_SE.json
@@ -82,14 +82,14 @@
},
"wifi": {
"title": "Inställningar för WiFi",
- "btn": "Wifi Settings",
+ "btn": "Inställningar för Wifi",
"ssid": "SSID"
},
"wg": {
"title": "WireGuard Settings",
"btn": "WireGuard Settings",
"vpnip": "VPN IP",
- "privkey": "Private Key",
+ "privkey": "Privat nyckel",
"host": "Remote IP",
"port": "Remote Port",
"pubkey": "Remote Public Key"
From f0506d185d501850c805359a3077f00da690a7bc Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 28 Aug 2024 12:33:52 +0200
Subject: [PATCH 080/142] New translations en.json (Swedish)
---
data/sv_SE.json | 184 ++++++++++++++++++++++++------------------------
1 file changed, 92 insertions(+), 92 deletions(-)
diff --git a/data/sv_SE.json b/data/sv_SE.json
index d4a3dacd..33672264 100644
--- a/data/sv_SE.json
+++ b/data/sv_SE.json
@@ -4,29 +4,29 @@
"home": {
"title": "Huvudmeny",
"btn": "Huvudmeny",
- "nav": "Home"
+ "nav": "Hem"
},
"save": "Spara Inställningar",
- "user": "Username",
- "pass": "Password",
+ "user": "Användarnamn",
+ "pass": "Lösenord",
"hasp": {
"title": "HASP Design",
"btn": "HASP Design",
- "theme": "UI Theme",
- "color1": "Primary color",
- "color2": "Secondary color",
- "pages": "Start Layout",
- "font": "Default Font",
- "startpage": "Startup Page",
- "startdim": "Startup Dim"
+ "theme": "UI Tema",
+ "color1": "Primärfärg",
+ "color2": "Sekundärfärg",
+ "pages": "Starta Layout",
+ "font": "Standardtypsnitt",
+ "startpage": "Startsida",
+ "startdim": "Startljusstyrka"
},
"screenshot": {
- "title": "Screenshot",
- "btn": "Screenshot",
- "nav": "Screenshot",
- "prev": "Prev Page",
- "next": "Next Page",
- "refresh": "Refresh"
+ "title": "Skärmbild",
+ "btn": "Skärmbild",
+ "nav": "Skärmbild",
+ "prev": "Föregående Sida",
+ "next": "Nästa Sida",
+ "refresh": "Uppdatera"
},
"info": {
"title": "Information",
@@ -34,48 +34,48 @@
"nav": "Information"
},
"config": {
- "title": "Configuration",
- "btn": "Configuration",
- "nav": "Settings"
+ "title": "Inställningar",
+ "btn": "Konfiguration",
+ "nav": "Inställningar"
},
"ota": {
- "title": "Firmware Update",
- "btn": "Firmware Update",
+ "title": "Firmware-uppdatering",
+ "btn": "Firmware-uppdatering",
"nav": "Firmware",
- "submit": "Update Firmware",
- "file": "Firmware File",
+ "submit": "Uppdatera Firmware",
+ "file": "Firmware-fil",
"url": "Firmware URL",
- "redirect": "Follow Redirects",
- "never": "Never",
- "strict": "Strict",
- "always": "Always"
+ "redirect": "Följ omdirigeringar",
+ "never": "Aldrig",
+ "strict": "Strikt",
+ "always": "Alltid"
},
"editor": {
- "title": "File Editor",
- "btn": "File Editor",
- "nav": "File Editor"
+ "title": "Filredigerare",
+ "btn": "Filredigerare",
+ "nav": "Filredigerare"
},
"reset": {
- "title": "Factory Reset",
- "btn": "Factory Reset",
- "warning": "Warning",
- "message": "This process will reset all settings to the default values. The internal flash will be erased and the device is restarted. You may need to connect to the WiFi AP displayed on the panel to reconfigure the device before accessing it again.",
- "fileloss": "ALL FILES WILL BE LOST!"
+ "title": "Fabriksåterställning",
+ "btn": "Fabriksåterställning",
+ "warning": "Varning",
+ "message": "Denna process kommer att återställa alla inställningar till standardvärden. Det interna minnet kommer att raderas och enheten startas om. Du kan behöva ansluta till WiFi AP som visas på panelen för att konfigurera om enheten innan du öppnar den igen.",
+ "fileloss": "ALLA FILLER KOMMER ATT FÖRLORAS!"
},
"reboot": {
- "title": "Rebooting...",
- "btn": "Restart",
- "nav": "Reboot",
- "message": "The device is rebooting."
+ "title": "Startar om...",
+ "btn": "Omstart",
+ "nav": "Omstart",
+ "message": "Enheten startar om."
},
"about": {
- "credits": "Based on the previous work of the following open source developers:",
- "copyright": "Copyright ",
- "rights": "All rights reserved.",
- "clause1": "Härmed beviljas tillstånd, utan kostnad, till alla personer som erhåller en kopia av denna programvara och tillhörande dokumentationsfiler (\"Programvaran\"), att hantera Programvaran utan begränsningar, inklusive men inte begränsat till rätten att använda, kopiera, modifiera, sammanfoga, publicera, distribuera, underlicensiera och/eller sälja kopior av Programvaran, samt att tillåta personer till vilka Programvaran tillhandahålls att göra detsamma, under förutsättning av följande villkor:",
+ "credits": "Baserat på det tidigare arbetet av följande utvecklare av öppen källkod:",
+ "copyright": "Upphovsrätt ",
+ "rights": "Alla rättigheter förbehållna.",
+ "clause1": "Härmed beviljas tillstånd, utan kostnad, till alla personer som erhåller en kopia av denna programvara och tillhörande dokumentation (\"Programvaran\"), att hantera Programvaran utan begränsningar, inklusive men inte begränsat till rätten att använda, kopiera, modifiera, sammanfoga, publicera, distribuera, underlicensiera och/eller sälja kopior av Programvaran, samt att tillåta personer till vilka Programvaran tillhandahålls att göra detsamma, under förutsättning av följande villkor:",
"clause2": "Ovanstående meddelande om upphovsrätt och detta tillståndsmeddelande ska inkluderas i alla kopior eller väsentliga delar av programvaran.",
"clause3": "PROGRAMVARAN TILLHANDAHÅLLS \"I BEFINTLIGT SKICK\", UTAN NÅGON SOM HELST GARANTI, VARE SIG UTTRYCKLIG ELLER UNDERFÖRSTÅDD, INKLUSIVE MEN INTE BEGRÄNSAT TILL GARANTIER OM SÄLJBARHET, LÄMPLIGHET FÖR ETT VISST ÄNDAMÅL OCH ICKE-INTRÅNG. UNDER INGA OMSTÄNDIGHETER SKALL FÖRFATTARNA ELLER UPPHOVSRÄTTSINNEHAVARNA VARA ANSVARIGA FÖR NÅGON TYP AV KRAV, SKADOR ELLER ANNAT ANSVAR, VARE SIG I KONTRAKT, SKADESTÅND ELLER ANNAT, SOM UPPSTÅR FRÅN, UR ELLER I SAMBAND MED PROGRAMVARAN ELLER ANVÄNDNINGEN ELLER ANDRA ÅTGÄRDER I SAMBAND MED PROGRAMVARAN.",
- "mit": "MIT License",
+ "mit": "MIT Licens",
"bsd": "BSD Licens",
"freebsd": "FreeBSD Licens",
"apache2": "Apache2 Licens"
@@ -86,77 +86,77 @@
"ssid": "SSID"
},
"wg": {
- "title": "WireGuard Settings",
- "btn": "WireGuard Settings",
- "vpnip": "VPN IP",
+ "title": "Inställningar för WireGuard",
+ "btn": "Inställningar för WireGuard",
+ "vpnip": "VPN IP-adress",
"privkey": "Privat nyckel",
- "host": "Remote IP",
- "port": "Remote Port",
- "pubkey": "Remote Public Key"
+ "host": "Fjärr-IP",
+ "port": "Fjärrport",
+ "pubkey": "Publik fjärrnyckel"
},
"mqtt": {
- "title": "MQTT Settings",
- "btn": "MQTT Settings",
- "name": "Hostname",
- "group": "Groupname",
+ "title": "MQTT Inställningar",
+ "btn": "MQTT Inställningar",
+ "name": "Servernamn",
+ "group": "Gruppnamn",
"host": "Broker",
"port": "Port",
- "node_t": "Node Topic",
- "group_t": "Group Topic",
- "broadcast_t": "Broadcast Topic",
- "hass_t": "HA LWT Topic"
+ "node_t": "Nod topic",
+ "group_t": "Grupp topic",
+ "broadcast_t": "Broadcast topic",
+ "hass_t": "HA LWT topic"
},
"http": {
- "title": "HTTP Settings",
- "btn": "HTTP Settings"
+ "title": "HTTP Inställningar",
+ "btn": "HTTP Inställningar"
},
"ftp": {
- "title": "FTP Settings",
- "btn": "FTP Settings",
+ "title": "FTP Inställningar",
+ "btn": "FTP Inställningar",
"port": "FTP Port",
- "pasv": "Passive Port"
+ "pasv": "Passiv port"
},
"gui": {
- "title": "Display Settings",
- "btn": "Display Settings",
+ "title": "Bildskärmsinställningar",
+ "btn": "Bildskärmsinställningar",
"antiburn": "Antiburn",
- "calibrate": "Calibrate"
+ "calibrate": "Kalibrera"
},
- "gpio": "GPIO Settings",
+ "gpio": "GPIO Inställningar",
"debug": {
- "title": "Debug Settings",
- "btn": "Debug Settings",
- "baud": "Baudrate",
- "tele": "Tele Period",
- "ansi": "Use ANSI codes",
- "host": "Syslog Server",
- "port": "Syslog Port",
+ "title": "Debug inställningar",
+ "btn": "Debug inställningar",
+ "baud": "Datahastighet",
+ "tele": "Telemetri period",
+ "ansi": "Använd ANSI-kod",
+ "host": "Syslog server",
+ "port": "Syslog port",
"ietf": "IETF (RFC 5424)",
"bsd": "BSD (RFC 3164)",
- "log": "Facility"
+ "log": "Facilitet"
},
"time": {
- "title": "Time Settings",
- "btn": "Time Settings",
+ "title": "Tidsinställningar",
+ "btn": "Tidsinställningar",
"region": "Region",
- "zone": "Timezone",
- "tz": "Timezone",
- "ntp": "NTP Servers"
+ "zone": "Tidszon",
+ "tz": "Tidszon",
+ "ntp": "NTP-servrar"
},
"region": {
"etc": "Etcetera ",
- "continents": "Continents ",
- "af": "Africa ",
- "as": "Asia ",
- "au": "Australia ",
- "aq": "Antarctica ",
- "eu": "Europe ",
- "na": "North America ",
- "sa": "South America ",
- "islands": "Islands ",
- "at": "Atlantic Ocean ",
- "in": "Indian Ocean ",
- "pa": "Pacific Ocean "
+ "continents": "Kontinenter ",
+ "af": "Afrika ",
+ "as": "Asien ",
+ "au": "Australien ",
+ "aq": "Antarktis",
+ "eu": "Europa ",
+ "na": "Nordamerika ",
+ "sa": "Sydamerika ",
+ "islands": "Öar ",
+ "at": "Atlanten ",
+ "in": "Indiska oceanen ",
+ "pa": "Stilla havet "
}
}
}
\ No newline at end of file
From b83276bca0d3780c0128f7fd7c919026f0151bbb Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 28 Aug 2024 12:33:53 +0200
Subject: [PATCH 081/142] New translations en_us.h (Swedish)
---
src/lang/sv_SE.h | 364 +++++++++++++++++++++++------------------------
1 file changed, 182 insertions(+), 182 deletions(-)
diff --git a/src/lang/sv_SE.h b/src/lang/sv_SE.h
index 048cb6e6..6659ffce 100644
--- a/src/lang/sv_SE.h
+++ b/src/lang/sv_SE.h
@@ -1,5 +1,5 @@
-// This translation file is maintained on https://crowdin.com/project/openhasp/
-// Do not edit directly!
+// Denna översättningsfil bibehålls på https://crowdin.com/project/openhasp/
+// Redigera inte direkt!
#ifndef HASP_LANG_SV_SE_H
#define HASP_LANG_SV_SE_H
@@ -12,231 +12,231 @@
#define D_YES "Ja"
#define D_NO "Nej"
-#define D_ERROR_OUT_OF_MEMORY "Out of memory"
-#define D_ERROR_UNKNOWN "Unknown error"
+#define D_ERROR_OUT_OF_MEMORY "Slut minne"
+#define D_ERROR_UNKNOWN "Okänt fel"
-#define D_CONFIG_NOT_CHANGED "Settings did not change"
-#define D_CONFIG_CHANGED "Settings changed"
-#define D_CONFIG_LOADED "Settings loaded"
+#define D_CONFIG_NOT_CHANGED "Inställningar ändrades inte"
+#define D_CONFIG_CHANGED "Inställningar ändrade"
+#define D_CONFIG_LOADED "Inställningarna inlästa"
-#define D_FILE_LOADING "Loading %s"
-#define D_FILE_LOADED "Loaded %s"
-#define D_FILE_LOAD_FAILED "Failed to load %s"
-#define D_FILE_SAVING "Saving %s"
-#define D_FILE_SAVED "Saved %s"
-#define D_FILE_SAVE_FAILED "Failed to save %s"
-#define D_FILE_NOT_FOUND "File not found"
+#define D_FILE_LOADING "Läser %s"
+#define D_FILE_LOADED "Läst %s"
+#define D_FILE_LOAD_FAILED "Misslyckades att läsa %s"
+#define D_FILE_SAVING "Sparar %s"
+#define D_FILE_SAVED "Sparat %s"
+#define D_FILE_SAVE_FAILED "Kunde inte spara %s"
+#define D_FILE_NOT_FOUND "Filen hittades inte"
#define D_FILE_SIZE_BYTES "bytes"
#define D_FILE_SIZE_KILOBYTES "KiB"
#define D_FILE_SIZE_MEGABYTES "MiB"
#define D_FILE_SIZE_GIGABYTES "GiB"
#define D_FILE_SIZE_TERABYTES "TiB"
-#define D_FILE_SIZE_DIVIDER 1024 // kibi or kilo bytes
-#define D_DECIMAL_POINT "." // decimal comma or point
+#define D_FILE_SIZE_DIVIDER 1024 // kibi eller kilo bytes
+#define D_DECIMAL_POINT "." // kommatecken eller punkt
-#define D_SERVICE_STARTING "Starting..."
-#define D_SERVICE_STARTED "Started"
-#define D_SERVICE_START_FAILED "Failed to start"
-#define D_SERVICE_STOPPED "Stopped"
-#define D_SERVICE_DISABLED "Disabled"
-#define D_SERVICE_CONNECTED "Connected"
-#define D_SERVICE_DISCONNECTED "Disconnected"
+#define D_SERVICE_STARTING "Startar..."
+#define D_SERVICE_STARTED "Startat"
+#define D_SERVICE_START_FAILED "Misslyckades att starta"
+#define D_SERVICE_STOPPED "Stoppat"
+#define D_SERVICE_DISABLED "Inaktiverad"
+#define D_SERVICE_CONNECTED "Ansluten"
+#define D_SERVICE_DISCONNECTED "Frånkopplad"
-#define D_SETTING_ENABLED "Enabled"
-#define D_SETTING_DISABLED "Disabled"
-#define D_SETTING_DEFAULT "Default"
+#define D_SETTING_ENABLED "Aktiverad"
+#define D_SETTING_DISABLED "Inaktiverad"
+#define D_SETTING_DEFAULT "Standard"
-#define D_NETWORK_IP_ADDRESS_RECEIVED "Received IP address %s"
+#define D_NETWORK_IP_ADDRESS_RECEIVED "Mottagen IP-adress %s"
#define D_NETWORK_ONLINE "online"
#define D_NETWORK_OFFLINE "offline"
-#define D_NETWORK_CONNECTION_FAILED "Connection failed"
+#define D_NETWORK_CONNECTION_FAILED "Anslutning misslyckades"
#define D_NETWORK_CONNECTION_UNAUTHORIZED "Auktorisering misslyckades"
#define D_MQTT_DEFAULT_NAME "plate_%s"
-#define D_MQTT_CONNECTING "Connecting..."
-#define D_MQTT_CONNECTED "Connected to broker %s as clientID %s"
-#define D_MQTT_NOT_CONNECTED "Not connected ???"
-#define D_MQTT_DISCONNECTING "Disconnecting..."
-#define D_MQTT_DISCONNECTED "Disconnected"
-#define D_MQTT_RECONNECTING "Disconnected from broker, reconnection..."
-#define D_MQTT_NOT_CONFIGURED "Broker not configured"
-#define D_MQTT_STARTED "Started: %d bytes"
-#define D_MQTT_FAILED "Failed:"
-#define D_MQTT_INVALID_TOPIC "Message has invalid topic"
-#define D_MQTT_SUBSCRIBED "Subscribed to %s"
-#define D_MQTT_NOT_SUBSCRIBED "Failed to subscribe to %s"
-#define D_MQTT_HA_AUTO_DISCOVERY "Register HA auto-discovery"
-#define D_MQTT_PAYLOAD_TOO_LONG "Payload too long (%u bytes)"
+#define D_MQTT_CONNECTING "Ansluter..."
+#define D_MQTT_CONNECTED "Ansluten till broker %s som clientID %s"
+#define D_MQTT_NOT_CONNECTED "Inte ansluten ???"
+#define D_MQTT_DISCONNECTING "Kopplar från..."
+#define D_MQTT_DISCONNECTED "Frånkopplad"
+#define D_MQTT_RECONNECTING "Frånkopplad från broker, återansluter..."
+#define D_MQTT_NOT_CONFIGURED "Broker är inte konfigurerad"
+#define D_MQTT_STARTED "Startat: %d bytes"
+#define D_MQTT_FAILED "Misslyckades:"
+#define D_MQTT_INVALID_TOPIC "Meddelande har ogiltigt topic"
+#define D_MQTT_SUBSCRIBED "Prenumererade på %s"
+#define D_MQTT_NOT_SUBSCRIBED "Misslyckades att prenumerera på %s"
+#define D_MQTT_HA_AUTO_DISCOVERY "Registrera HA auto-discovery"
+#define D_MQTT_PAYLOAD_TOO_LONG "Payload för lång (%u bytes)"
-#define D_TELNET_CLOSING_CONNECTION "Closing session from %s"
-#define D_TELNET_CLIENT_LOGIN_FROM "Client login from %s"
-#define D_TELNET_CLIENT_CONNECT_FROM "Client connected from %s"
-#define D_TELNET_CLIENT_NOT_CONNECTED "Client NOT connected"
-#define D_TELNET_INCORRECT_LOGIN_ATTEMPT "Incorrect login attempt from %s"
-#define D_TELNET_STARTED "Telnet console started"
-#define D_TELNET_FAILED "Failed to start telnet console"
-#define D_TELNET_CLIENT_CONNECTED "Client connected"
-#define D_TELNET_CLIENT_REJECTED "Client rejected"
+#define D_TELNET_CLOSING_CONNECTION "Stänger session från %s"
+#define D_TELNET_CLIENT_LOGIN_FROM "Klientinloggning från %s"
+#define D_TELNET_CLIENT_CONNECT_FROM "Klient ansluten från %s"
+#define D_TELNET_CLIENT_NOT_CONNECTED "Klient INTE ansluten"
+#define D_TELNET_INCORRECT_LOGIN_ATTEMPT "Felaktigt inloggningsförsök från %s"
+#define D_TELNET_STARTED "Telnet-konsol startad"
+#define D_TELNET_FAILED "Misslyckades att starta telnet-konsolen"
+#define D_TELNET_CLIENT_CONNECTED "Klient ansluten"
+#define D_TELNET_CLIENT_REJECTED "Klient avvisad"
-#define D_HASP_INVALID_PAGE "Invalid page %u"
-#define D_HASP_INVALID_LAYER "Cannot clear system layer"
-#define D_HASP_CHANGE_PAGE "Changing page to %u"
-#define D_HASP_CLEAR_PAGE "Clearing page %u"
+#define D_HASP_INVALID_PAGE "Ogiltig sida %u"
+#define D_HASP_INVALID_LAYER "Kan inte rensa systemlager"
+#define D_HASP_CHANGE_PAGE "Byter sida till %u"
+#define D_HASP_CLEAR_PAGE "Rensar sida %u"
-#define D_OBJECT_DELETED "Object deleted"
-#define D_OBJECT_UNKNOWN "Unknown object"
-#define D_OBJECT_MISMATCH "Objects DO NOT match!"
-#define D_OBJECT_LOST "Lost object!"
-#define D_OBJECT_CREATE_FAILED "Failed to create object id %u"
-#define D_OBJECT_PAGE_UNKNOWN "Page ID %u not defined"
-#define D_OBJECT_EVENT_UNKNOWN "Unknown Event %d"
+#define D_OBJECT_DELETED "Objektet borttaget"
+#define D_OBJECT_UNKNOWN "Okänt objekt"
+#define D_OBJECT_MISMATCH "Objekt matchar INTE!"
+#define D_OBJECT_LOST "Förlorat objekt!"
+#define D_OBJECT_CREATE_FAILED "Misslyckades att skapa objekt-id %u"
+#define D_OBJECT_PAGE_UNKNOWN "Sida ID %u inte skapad"
+#define D_OBJECT_EVENT_UNKNOWN "Okänd händelse %d"
-#define D_ATTRIBUTE_UNKNOWN "Unknown property %s"
-// D_ATTRIBUTE_OBSOLETE D_ATTRIBUTE_INSTEAD can be used together or just D_ATTRIBUTE_OBSOLETE alone
-#define D_ATTRIBUTE_OBSOLETE "%s is obsolete"
-#define D_ATTRIBUTE_INSTEAD ", use %s instead"
-#define D_ATTRIBUTE_READ_ONLY "%s is read-only"
-#define D_ATTRIBUTE_PAGE_METHOD_INVALID "Unable to call %s on a page"
-#define D_ATTRIBUTE_ALIGN_INVALID "Invalid align property: %s"
-#define D_ATTRIBUTE_COLOR_INVALID "Invalid color property: %s"
-#define D_ATTRIBUTE_LONG_MODE_INVALID "Invalid long mode: %s"
+#define D_ATTRIBUTE_UNKNOWN "Okänd egenskap %s"
+// D_ATTRIBUTE_OBSOLETE D_ATTRIBUTE_INSTEAD kan användas tillsammans eller bara D_ATTRIBUTE_OBSOLETE ensam
+#define D_ATTRIBUTE_OBSOLETE "%s är föråldrad"
+#define D_ATTRIBUTE_INSTEAD ", använd %s istället"
+#define D_ATTRIBUTE_READ_ONLY "%s är skrivskyddad"
+#define D_ATTRIBUTE_PAGE_METHOD_INVALID "Kan inte anropa %s på en sida"
+#define D_ATTRIBUTE_ALIGN_INVALID "Ogiltig align-värde: %s"
+#define D_ATTRIBUTE_COLOR_INVALID "Ogiltig färg-värde: %s"
+#define D_ATTRIBUTE_LONG_MODE_INVALID "Ogiltigt long-läge: %s"
-#define D_OOBE_SSID_VALIDATED "SSID %s validated"
-#define D_OOBE_AUTO_CALIBRATE "Auto calibrate enabled"
-#define D_OOBE_CALIBRATED "Already calibrated"
+#define D_OOBE_SSID_VALIDATED "SSID %s validerat"
+#define D_OOBE_AUTO_CALIBRATE "Automatisk kalibrering aktiverad"
+#define D_OOBE_CALIBRATED "Redan kalibrerad"
-#define D_DISPATCH_COMMAND_NOT_FOUND "Command '%s' not found"
-#define D_DISPATCH_INVALID_PAGE "Invalid page %s"
-#define D_DISPATCH_REBOOT "Rebooting the MCU now!"
+#define D_DISPATCH_COMMAND_NOT_FOUND "Kommando '%s' hittades inte
+#define D_DISPATCH_INVALID_PAGE "Ogiltig sida %s"
+#define D_DISPATCH_REBOOT "Startar om MCU nu!"
-#define D_JSON_FAILED "JSON parsing failed:"
-#define D_JSONL_FAILED "JSONL parsing failed at line %u"
-#define D_JSONL_SUCCEEDED "Jsonl fully parsed"
+#define D_JSON_FAILED "JSON parsning misslyckades:"
+#define D_JSONL_FAILED "JSONL parsning misslyckades på rad %u"
+#define D_JSONL_SUCCEEDED "Jsonl helt tolkad"
-#define D_OTA_CHECK_UPDATE "Trying update URL: %s"
-#define D_OTA_CHECK_COMPLETE "Update check complete"
+#define D_OTA_CHECK_UPDATE "Försöker uppdatera URL: %s"
+#define D_OTA_CHECK_COMPLETE "Uppdateringskontroll slutförd"
#define D_OTA_CHECK_FAILED "Uppdateringskontroll misslyckades: %s"
-#define D_OTA_UPDATE_FIRMWARE "OTA Firmware Update"
-#define D_OTA_UPDATE_COMPLETE "OTA Update complete"
-#define D_OTA_UPDATE_APPLY "Applying Firmware & Reboot"
-#define D_OTA_UPDATE_FAILED "OTA Update failed"
-#define D_OTA_UPDATING_FIRMWARE "Updating firmware..."
-#define D_OTA_UPDATING_FILESYSTEM "Updating filesystem..."
+#define D_OTA_UPDATE_FIRMWARE "OTA Uppdatering"
+#define D_OTA_UPDATE_COMPLETE "OTA Uppdatering klar"
+#define D_OTA_UPDATE_APPLY "Sparar fast programvara och startar om"
+#define D_OTA_UPDATE_FAILED "OTA Uppdatering misslyckades"
+#define D_OTA_UPDATING_FIRMWARE "Uppdatera den inbyggda programvaran..."
+#define D_OTA_UPDATING_FILESYSTEM "Uppdaterar filsystemet..."
#define D_HTTP_HASP_DESIGN "HASP Design"
#define D_HTTP_INFORMATION "Information"
-#define D_HTTP_HTTP_SETTINGS "HTTP Settings"
-#define D_HTTP_FTP_SETTINGS "FTP Settings"
-#define D_HTTP_WIFI_SETTINGS "Wifi Settings"
-#define D_HTTP_WIREGUARD_SETTINGS "WireGuard Settings"
-#define D_HTTP_MQTT_SETTINGS "MQTT Settings"
-#define D_HTTP_GPIO_SETTINGS "GPIO Settings"
-#define D_HTTP_MDNS_SETTINGS "mDNS Settings"
-#define D_HTTP_TELNET_SETTINGS "Telnet Settings"
-#define D_HTTP_DEBUG_SETTINGS "Debug Settings"
-#define D_HTTP_GUI_SETTINGS "Display Settings"
-#define D_HTTP_SAVE_SETTINGS "Save Settings"
-#define D_HTTP_UPLOAD_FILE "Upload File"
-#define D_HTTP_ERASE_DEVICE "Reset All Settings"
-#define D_HTTP_ADD_GPIO "Add New Pin"
-#define D_HTTP_BACK "Back"
-#define D_HTTP_REFRESH "Refresh"
-#define D_HTTP_PREV_PAGE "Prev Page"
-#define D_HTTP_NEXT_PAGE "Next Page"
-#define D_HTTP_CALIBRATE "Calibrate"
-#define D_HTTP_ANTIBURN "Run Anti Burn-in"
-#define D_HTTP_SCREENSHOT "Screenshot"
-#define D_HTTP_FILE_BROWSER "File Editor"
-#define D_HTTP_FIRMWARE_UPGRADE "Firmware Upgrade"
-#define D_HTTP_UPDATE_FIRMWARE "Update Firmware"
-#define D_HTTP_FACTORY_RESET "Factory Reset"
-#define D_HTTP_MAIN_MENU "Main Menu"
-#define D_HTTP_REBOOT "Restart"
-#define D_HTTP_CONFIGURATION "Configuration"
-#define D_HTTP_CONFIG_CHANGED \
- "The configuration has changed, please click Restart to save changes to flash."
-#define D_HTTP_SENDING_PAGE "Sent %S page to %s"
-#define D_HTTP_FOOTER "by Francis Van Roie"
+#define D_HTTP_HTTP_SETTINGS "HTTP-inställningar"
+#define D_HTTP_FTP_SETTINGS "FTP-inställningar"
+#define D_HTTP_WIFI_INSTÄLLNINGAR "Wifi-inställningar"
+#define D_HTTP_WIREGUARD_INSTÄLLNINGAR "WireGuard inställningar"
+#define D_HTTP_MQTT_INSTÄLLNINGAR "MQTT-inställningar"
+#define D_HTTP_GPIO_SETTINGS "GPIO-inställningar"
+#define D_HTTP_MDNS_INSTÄLLNINGAR "mDNS-inställningar"
+#define D_HTTP_TELNET_INSTÄLLNINGAR "Telnet-inställningar"
+#define D_HTTP_DEBUG_INSTÄLLNINGAR "Debug-inställningar"
+#define D_HTTP_GUI_INSTÄLLNINGAR "Visningsinställningar"
+#define D_HTTP_SAVE_SETTINGS "Spara inställningar"
+#define D_HTTP_UPLOAD_FILE "Ladda upp fil"
+#define D_HTTP_ERASE_DEVICE "Återställ alla inställningar"
+#define D_HTTP_ADD_GPIO "Lägg till ny GPIO"
+#define D_HTTP_BACK "Tillbaka"
+#define D_HTTP_REFRESH "Uppdatera"
+#define D_HTTP_PREV_PAGE "Föregående sida"
+#define D_HTTP_NEXT_PAGE "Nästa sida"
+#define D_HTTP_CALIBRATE "Kalibrera"
+#define D_HTTP_ANTIBURN "Kör Anti Burn-in"
+#define D_HTTP_SCREENSHOT "Skärmdump"
+#define D_HTTP_FILE_BROWSER "Filredigerare"
+#define D_HTTP_FIRMWARE_UPGRADE "Uppgradering av fast programvara"
+#define D_HTTP_UPDATE_FIRMWARE "Uppdatera fast programvara"
+#define D_HTTP_FACTORY_RESET "Fabriksåterställning"
+#define D_HTTP_MAIN_MENU "Huvudmeny"
+#define D_HTTP_REBOOT "Omstart"
+#define D_HTTP_CONFIGURATION "Konfiguration"
+#define D_HTTP_CONFIG_CHANGED \
+ "Konfigurationen har ändrats, klicka på Starta om för att spara ändringar."
+#define D_HTTP_SENDING_PAGE "Skickat %S sida till %s"
+#define D_HTTP_FOOTER "av Francis Van Roie"
#define D_INFO_VERSION "Version"
-#define D_INFO_BUILD_DATETIME "Build DateTime"
-#define D_INFO_ENVIRONMENT "Environment"
+#define D_INFO_BUILD_DATETIME "Byggd datum/tid"
+#define D_INFO_ENVIRONMENT "Miljö"
#define D_INFO_UPTIME "Uptime"
-#define D_INFO_FREE_HEAP "Free Heap"
-#define D_INFO_FREE_BLOCK "Free Block"
-#define D_INFO_DEVICE_MEMORY "Device Memory"
-#define D_INFO_LVGL_MEMORY "LVGL Memory"
-#define D_INFO_TOTAL_MEMORY "Total"
-#define D_INFO_FREE_MEMORY "Free"
-#define D_INFO_FRAGMENTATION "Fragmentation"
-#define D_INFO_PSRAM_FREE "PSRam Free"
-#define D_INFO_PSRAM_SIZE "PSRam Size"
-#define D_INFO_FLASH_SIZE "Flash Size"
-#define D_INFO_SKETCH_USED "Program Size Used"
-#define D_INFO_SKETCH_FREE "Program Size Free"
-#define D_INFO_FS_SIZE "Filesystem Size"
-#define D_INFO_FS_USED "Filesystem Used"
-#define D_INFO_FS_FREE "Filesystem Free"
-#define D_INFO_MODULE "Module"
-#define D_INFO_MODEL "Model"
-#define D_INFO_FREQUENCY "Frequency"
-#define D_INFO_CORE_VERSION "Core Version"
-#define D_INFO_RESET_REASON "Reset Reason"
+#define D_INFO_FREE_HEAP "Ledig Heap"
+#define D_INFO_FREE_BLOCK "Lediga Block"
+#define D_INFO_DEVICE_MEMORY "Enhetsminne"
+#define D_INFO_LVGL_MEMORY "LVGL-minne"
+#define D_INFO_TOTAL_MEMORY "Totalt"
+#define D_INFO_FREE_MEMORY "Ledigt"
+#define D_INFO_FRAGMENTATION "Fragmentering"
+#define D_INFO_PSRAM_FREE "Ledigt PSRam"
+#define D_INFO_PSRAM_SIZE "PSRam storlek"
+#define D_INFO_FLASH_SIZE "Flash storlek"
+#define D_INFO_SKETCH_USED "Använd programstorlek"
+#define D_INFO_SKETCH_FREE "Ledig programstorlek"
+#define D_INFO_FS_SIZE "Storlek på filsystem"
+#define D_INFO_FS_USED "Använt av filsystem"
+#define D_INFO_FS_FREE "Filsystem ledigt"
+#define D_INFO_MODULE "Modul"
+#define D_INFO_MODEL "Modell"
+#define D_INFO_FREQUENCY "Frekvens"
+#define D_INFO_CORE_VERSION "Core version"
+#define D_INFO_RESET_REASON "Omstartsorsak"
#define D_INFO_STATUS "Status"
#define D_INFO_SERVER "Server"
#define D_INFO_USERNAME "Username"
-#define D_INFO_CLIENTID "Client ID"
-// #define D_INFO_CONNECTED "Connected"
-// #define D_INFO_DISCONNECTED "Disconnected"
-#define D_INFO_RECEIVED "Received"
-#define D_INFO_PUBLISHED "Published"
-#define D_INFO_FAILED "Failed"
+#define D_INFO_CLIENTID "Klient-ID"
+// #define D_INFO_CONNECTED "Ansluten"
+// #define D_INFO_DISCONNECTED "Frånkopplad"
+#define D_INFO_RECEIVED "Mottaget"
+#define D_INFO_PUBLISHED "Publicerat"
+#define D_INFO_FAILED "Misslyckade"
#define D_INFO_ETHERNET "Ethernet"
#define D_INFO_WIFI "Wifi"
#define D_INFO_WIREGUARD "WireGuard"
-#define D_INFO_LINK_SPEED "Link Speed"
-#define D_INFO_FULL_DUPLEX "Full Duplex"
+#define D_INFO_LINK_SPEED "Länkhastighet"
+#define D_INFO_FULL_DUPLEX "Full duplex"
#define D_INFO_BSSID "BSSID"
#define D_INFO_SSID "SSID"
-#define D_INFO_RSSI "Signal Strength"
-#define D_INFO_IP_ADDRESS "IP Address"
-#define D_INFO_MAC_ADDRESS "MAC Address"
+#define D_INFO_RSSI "Signalstyrka"
+#define D_INFO_IP_ADDRESS "IP-adress"
+#define D_INFO_MAC_ADDRESS "MAC-adress"
#define D_INFO_GATEWAY "Gateway"
-#define D_INFO_DNS_SERVER "DNS Server"
-#define D_INFO_ENDPOINT_IP "Endpoint IP"
-#define D_INFO_ENDPOINT_PORT "Endpoint Port"
+#define D_INFO_DNS_SERVER "DNS-server"
+#define D_INFO_ENDPOINT_IP "Slutpunkt IP"
+#define D_INFO_ENDPOINT_PORT "Slutpunkt port"
-#define D_OOBE_MSG "Tap the screen to setup WiFi or connect to this Access Point:"
-#define D_OOBE_SCAN_TO_CONNECT "Scan to connect"
+#define D_OOBE_MSG "Tryck på skärmen för att konfigurera WiFi eller ansluta till denna accesspunkt:"
+#define D_OOBE_SCAN_TO_CONNECT "Skanna för att ansluta"
-#define D_WIFI_CONNECTING_TO "Connecting to %s"
-#define D_WIFI_CONNECTED_TO "Connected to %s, requesting IP..."
-#define D_WIFI_RSSI_EXCELLENT "Excellent"
-#define D_WIFI_RSSI_GOOD "Good"
-#define D_WIFI_RSSI_FAIR "Fair"
-#define D_WIFI_RSSI_WEAK "Weak"
-#define D_WIFI_RSSI_BAD "Very bad"
+#define D_WIFI_CONNECTING_TO "Ansluter till %s"
+#define D_WIFI_CONNECTED_TO "Ansluten till %s, begär IP..."
+#define D_WIFI_RSSI_EXCELLENT "Utmärkt"
+#define D_WIFI_RSSI_GOOD "Bra"
+#define D_WIFI_RSSI_FAIR "Hygglig"
+#define D_WIFI_RSSI_WEAK "Svag"
+#define D_WIFI_RSSI_BAD "Mycket dålig"
-#define D_WG_INITIALIZED "Initialized"
-#define D_WG_BAD_CONFIG "Missing or bad configuration"
+#define D_WG_INITIALIZED "Initierad"
+#define D_WG_BAD_CONFIG "Saknad eller felaktig konfiguration"
-#define D_GPIO_SWITCH "Switch"
-#define D_GPIO_BUTTON "Push Button"
-#define D_GPIO_TOUCH "Capacitive Touch"
-#define D_GPIO_LED "Led"
-#define D_GPIO_LED_R "Mood Red"
-#define D_GPIO_LED_G "Mood Green"
-#define D_GPIO_LED_B "Mood Blue"
-#define D_GPIO_POWER_RELAY "Power Relay"
-#define D_GPIO_LIGHT_RELAY "Light Relay"
+#define D_GPIO_SWITCH "Omkopplare"
+#define D_GPIO_BUTTON "Tryckknapp"
+#define D_GPIO_TOUCH "Kapacitiv beröring"
+#define D_GPIO_LED "Lysdiod"
+#define D_GPIO_LED_R "Stämning röd"
+#define D_GPIO_LED_G "Stämning grön"
+#define D_GPIO_LED_B "Stämning blå"
+#define D_GPIO_POWER_RELAY "Effektrelä"
+#define D_GPIO_LIGHT_RELAY "Relä"
#define D_GPIO_PWM "PWM"
#define D_GPIO_DAC "DAC"
-#define D_GPIO_SERIAL_DIMMER "Serial Dimmer"
-#define D_GPIO_UNKNOWN "Unknown"
-#define D_GPIO_PIN "Pin"
-#define D_GPIO_GROUP "Group"
-#define D_GPIO_GROUP_NONE "None"
+#define D_GPIO_SERIAL_DIMMER "Seriell dimmer"
+#define D_GPIO_UNKNOWN "Okänt"
+#define D_GPIO_PIN "GPIO"
+#define D_GPIO_GROUP "Grupp"
+#define D_GPIO_GROUP_NONE "Ingen"
#define D_GPIO_STATE_NORMAL "Normal"
-#define D_GPIO_STATE_INVERTED "Inverted"
+#define D_GPIO_STATE_INVERTED "Inverterad"
#endif
\ No newline at end of file
From be953b904a389b723e7a8590f0eae7fa0f09df2e Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 28 Aug 2024 21:49:56 +0200
Subject: [PATCH 082/142] New translations en.json (Swedish)
---
data/sv_SE.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/data/sv_SE.json b/data/sv_SE.json
index 33672264..a500ed96 100644
--- a/data/sv_SE.json
+++ b/data/sv_SE.json
@@ -82,7 +82,7 @@
},
"wifi": {
"title": "Inställningar för WiFi",
- "btn": "Inställningar för Wifi",
+ "btn": "Inställningar för WiFi",
"ssid": "SSID"
},
"wg": {
@@ -124,8 +124,8 @@
},
"gpio": "GPIO Inställningar",
"debug": {
- "title": "Debug inställningar",
- "btn": "Debug inställningar",
+ "title": "Debug Inställningar",
+ "btn": "Debug Inställningar",
"baud": "Datahastighet",
"tele": "Telemetri period",
"ansi": "Använd ANSI-kod",
From 24c39a4b7155ddfb9c0fa391cf926d234663a1f9 Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Wed, 28 Aug 2024 23:04:50 +0200
Subject: [PATCH 083/142] New translations en_us.h (Swedish)
---
src/lang/sv_SE.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/lang/sv_SE.h b/src/lang/sv_SE.h
index 6659ffce..35e7628c 100644
--- a/src/lang/sv_SE.h
+++ b/src/lang/sv_SE.h
@@ -1,5 +1,5 @@
-// Denna översättningsfil bibehålls på https://crowdin.com/project/openhasp/
-// Redigera inte direkt!
+// This translation file is maintained on https://crowdin.com/project/openhasp/
+// Do not edit directly!
#ifndef HASP_LANG_SV_SE_H
#define HASP_LANG_SV_SE_H
From 1e0b85b3e4ba09d71be059ba2ece161483cc777b Mon Sep 17 00:00:00 2001
From: fvanroie <15969459+fvanroie@users.noreply.github.com>
Date: Thu, 29 Aug 2024 00:32:09 +0200
Subject: [PATCH 084/142] New translations en.json (Swedish)
---
data/sv_SE.json | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/data/sv_SE.json b/data/sv_SE.json
index a500ed96..f308542f 100644
--- a/data/sv_SE.json
+++ b/data/sv_SE.json
@@ -70,11 +70,11 @@
},
"about": {
"credits": "Baserat på det tidigare arbetet av följande utvecklare av öppen källkod:",
- "copyright": "Upphovsrätt ",
+ "copyright": "Copyright ",
"rights": "Alla rättigheter förbehållna.",
- "clause1": "Härmed beviljas tillstånd, utan kostnad, till alla personer som erhåller en kopia av denna programvara och tillhörande dokumentation (\"Programvaran\"), att hantera Programvaran utan begränsningar, inklusive men inte begränsat till rätten att använda, kopiera, modifiera, sammanfoga, publicera, distribuera, underlicensiera och/eller sälja kopior av Programvaran, samt att tillåta personer till vilka Programvaran tillhandahålls att göra detsamma, under förutsättning av följande villkor:",
- "clause2": "Ovanstående meddelande om upphovsrätt och detta tillståndsmeddelande ska inkluderas i alla kopior eller väsentliga delar av programvaran.",
- "clause3": "PROGRAMVARAN TILLHANDAHÅLLS \"I BEFINTLIGT SKICK\", UTAN NÅGON SOM HELST GARANTI, VARE SIG UTTRYCKLIG ELLER UNDERFÖRSTÅDD, INKLUSIVE MEN INTE BEGRÄNSAT TILL GARANTIER OM SÄLJBARHET, LÄMPLIGHET FÖR ETT VISST ÄNDAMÅL OCH ICKE-INTRÅNG. UNDER INGA OMSTÄNDIGHETER SKALL FÖRFATTARNA ELLER UPPHOVSRÄTTSINNEHAVARNA VARA ANSVARIGA FÖR NÅGON TYP AV KRAV, SKADOR ELLER ANNAT ANSVAR, VARE SIG I KONTRAKT, SKADESTÅND ELLER ANNAT, SOM UPPSTÅR FRÅN, UR ELLER I SAMBAND MED PROGRAMVARAN ELLER ANVÄNDNINGEN ELLER ANDRA ÅTGÄRDER I SAMBAND MED PROGRAMVARAN.",
+ "clause1": "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:",
+ "clause2": "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.",
+ "clause3": "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
"mit": "MIT Licens",
"bsd": "BSD Licens",
"freebsd": "FreeBSD Licens",
From 707078560d0e451e03ac323480e2457a2d8dea37 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 29 Aug 2024 15:58:44 +0200
Subject: [PATCH 085/142] Disable useSoftTabs #788
---
data/script.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/data/script.js b/data/script.js
index 93a1d96d..7458a17c 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1 @@
-var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.35.3")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:!0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
+var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.35.3")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
From 52259a34a0c66f56fae5b01acd305793e3389a6d Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Thu, 29 Aug 2024 23:07:19 +0200
Subject: [PATCH 086/142] Update ace.js to 1.36.1
---
data/edit.htm | 2 +-
data/script.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/edit.htm b/data/edit.htm
index 1a112286..cc93ecf5 100644
--- a/data/edit.htm
+++ b/data/edit.htm
@@ -1 +1 @@
-openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
+openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
diff --git a/data/script.js b/data/script.js
index 7458a17c..1ad21431 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1 @@
-var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.35.3")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
+var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.36.1")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
From 53bd3281783c78be7d132ad5c0306de0c124b397 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Fri, 30 Aug 2024 17:19:14 +0200
Subject: [PATCH 087/142] Update ace.js to 1.36.2
---
data/edit.htm | 2 +-
data/script.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/edit.htm b/data/edit.htm
index cc93ecf5..87e87abc 100644
--- a/data/edit.htm
+++ b/data/edit.htm
@@ -1 +1 @@
-openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
+openHASP File Editor- New File
- Upload Files
- Edit
- Preview
- Download
- Delete
\ No newline at end of file
diff --git a/data/script.js b/data/script.js
index 1ad21431..ec3ae438 100644
--- a/data/script.js
+++ b/data/script.js
@@ -1 +1 @@
-var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.36.1")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
+var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.36.2")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='
',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`\n ${e}\n
`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))}));
\ No newline at end of file
From ff83c7717c409db748501567e66f1eac3a36152f Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Sat, 31 Aug 2024 23:43:08 +0200
Subject: [PATCH 088/142] Test platform 5.4.0 for rc14 #643
---
platformio.ini | 2 +-
user_setups/esp32/_esp32.ini | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/platformio.ini b/platformio.ini
index 90ddcee9..13f1f16b 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -75,7 +75,7 @@ build_flags =
-D HASP_VER_MAJ=0
-D HASP_VER_MIN=7
;-D HASP_VER_REV=4
- -D HASP_VER_REV=0-rc13
+ -D HASP_VER_REV=0-rc14
;-D HASP_VER_REV=4-rc1
${override.build_flags}
diff --git a/user_setups/esp32/_esp32.ini b/user_setups/esp32/_esp32.ini
index 93079589..9d82084a 100644
--- a/user_setups/esp32/_esp32.ini
+++ b/user_setups/esp32/_esp32.ini
@@ -145,8 +145,8 @@ framework = arduino
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.08.01/platform-espressif32.zip
;platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
;;;platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.11.01/platform-espressif32.zip
-platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
-;platform = espressif32@5.3.0
+;platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
+platform = espressif32@5.4.0
lib_ignore =
${esp32.lib_ignore}
LittleFS_esp32 ; Not needed for Arduino v2
From 80a9ddb3ea038f1d5702dd39637b0f9892689092 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Sun, 1 Sep 2024 16:21:18 +0200
Subject: [PATCH 089/142] Downgrade platform
---
user_setups/esp32/_esp32.ini | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/user_setups/esp32/_esp32.ini b/user_setups/esp32/_esp32.ini
index 9d82084a..7243e02e 100644
--- a/user_setups/esp32/_esp32.ini
+++ b/user_setups/esp32/_esp32.ini
@@ -145,8 +145,8 @@ framework = arduino
; platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.08.01/platform-espressif32.zip
;platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
;;;platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.11.01/platform-espressif32.zip
-;platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
-platform = espressif32@5.4.0
+platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip
+;platform = espressif32@5.4.0
lib_ignore =
${esp32.lib_ignore}
LittleFS_esp32 ; Not needed for Arduino v2
From 0f64a3b0f457414a534e62855885af05b35d0c05 Mon Sep 17 00:00:00 2001
From: Shubham Sharma <10323297+shubham-vunet@users.noreply.github.com>
Date: Wed, 2 Oct 2024 21:17:45 +0530
Subject: [PATCH 090/142] Add "Lilygo T-Panel v1.2" pinmap and touch screen
---
src/drv/tft/tft_driver_arduinogfx.cpp | 22 ++++++-
src/sys/svc/hasp_http_async.cpp | 2 +-
user_setups/esp32s3/lilygo-t-panel.ini | 87 ++++++++++++++++++++++++++
3 files changed, 109 insertions(+), 2 deletions(-)
create mode 100644 user_setups/esp32s3/lilygo-t-panel.ini
diff --git a/src/drv/tft/tft_driver_arduinogfx.cpp b/src/drv/tft/tft_driver_arduinogfx.cpp
index ae73d504..5c80d750 100644
--- a/src/drv/tft/tft_driver_arduinogfx.cpp
+++ b/src/drv/tft/tft_driver_arduinogfx.cpp
@@ -25,7 +25,27 @@ void ArduinoGfx::init(int w, int h)
{
LOG_TRACE(TAG_TFT, F(D_SERVICE_STARTING));
-#if(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(LILYGO_T_RGB)
+#if(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(LILYGO_T_PANEL)
+
+ // pinMode(TFT_SCLK, OUTPUT);
+ // pinMode(TFT_MOSI, OUTPUT);
+ // pinMode(TFT_MISO, OUTPUT);
+ Arduino_DataBus* bus = new Arduino_XL9535SWSPI(17 /* SDA */, 18 /* SCL */, -1 /* XL PWD */, 17 /* XL CS */,
+ 15 /* XL SCK */, 16 /* XL MOSI */);
+ Arduino_ESP32RGBPanel *rgbpanel = new Arduino_ESP32RGBPanel(
+ -1 /* DE */, TFT_VSYNC /* VSYNC */, TFT_HSYNC /* HSYNC */, TFT_PCLK /* PCLK */,
+ TFT_B0 /* B0 */, TFT_B1 /* B1 */, TFT_B2 /* B2 */, TFT_B3 /* B3 */, TFT_B4 /* B4 */,
+ TFT_G0 /* G0 */, TFT_G1 /* G1 */, TFT_G2 /* G2 */, TFT_G3 /* G3 */, TFT_G4 /* G4 */, TFT_G5 /* G5 */,
+ TFT_R0 /* R0 */, TFT_R1 /* R1 */, TFT_R2 /* R2 */, TFT_R3 /* R3 */, TFT_R4 /* R4 */,
+ 1 /* hsync_polarity */, 20 /* hsync_front_porch */, 2 /* hsync_pulse_width */, 0 /* hsync_back_porch */,
+ 1 /* vsync_polarity */, 30 /* vsync_front_porch */, 8 /* vsync_pulse_width */, 1 /* vsync_back_porch */,
+ 10 /* pclk_active_neg */, 6000000L /* prefer_speed */, false /* useBigEndian */,
+ 0 /* de_idle_high*/, 0 /* pclk_idle_high */);
+
+ tft = new Arduino_RGB_Display(TFT_WIDTH /* width */, TFT_HEIGHT /* height */, rgbpanel, 0 /* rotation */, true /* auto_flush */,
+ bus, -1 /* RST */, st7701_sensecap_indicator_init_operations, sizeof(st7701_sensecap_indicator_init_operations));
+
+#elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(LILYGO_T_RGB)
Wire.begin(8 /* SDA */, 48 /* SCL */, 800000L /* speed */);
Arduino_DataBus* bus = new Arduino_XL9535SWSPI(8 /* SDA */, 48 /* SCL */, 2 /* XL PWD */, 3 /* XL CS */,
5 /* XL SCK */, 4 /* XL MOSI */);
diff --git a/src/sys/svc/hasp_http_async.cpp b/src/sys/svc/hasp_http_async.cpp
index e4e882ef..5a561bca 100644
--- a/src/sys/svc/hasp_http_async.cpp
+++ b/src/sys/svc/hasp_http_async.cpp
@@ -1311,7 +1311,7 @@ void webHandleGuiConfig(AsyncWebServerRequest* request)
httpMessage += getOption(-1, F("None"), bcklpin == -1);
#if defined(ARDUINO_ARCH_ESP32)
add_gpio_select_option(httpMessage, 5, bcklpin); // D8 on ESP32 for D1 mini 32
- add_gpio_select_option(httpMessage, 12, bcklpin); // TFT_LED on the Liligo Pi
+ add_gpio_select_option(httpMessage, 12, bcklpin); // TFT_LED on the Lilygo Pi
add_gpio_select_option(httpMessage, 13, bcklpin); // TFT_LED on the D1 R32 + Waveshare
add_gpio_select_option(httpMessage, 15, bcklpin); // TFT_LED on the AZ Touch
add_gpio_select_option(httpMessage, 16, bcklpin); // D4 on ESP32 for D1 mini 32
diff --git a/user_setups/esp32s3/lilygo-t-panel.ini b/user_setups/esp32s3/lilygo-t-panel.ini
new file mode 100644
index 00000000..d0f4868e
--- /dev/null
+++ b/user_setups/esp32s3/lilygo-t-panel.ini
@@ -0,0 +1,87 @@
+;***************************************************;
+; Lilygo T-Panel S3, 4-Inch Touch Screen ;
+; - Custom esp32-s3 board ;
+; - st7701s TFT ;
+; - CST3240 touch controller ;
+; - IO Expansion: XL9535 ;
+;***************************************************;
+
+[lilygo-t-panel]
+extends = arduino_esp32s3_v2
+board = esp32-s3-devkitc-1
+board_build.arduino.memory_type = qio_opi
+
+build_flags =
+ -D HASP_MODEL="Lilygo T-Panel v1.2"
+ ${arduino_esp32s3_v2.build_flags}
+ ${esp32s3.ps_ram}
+ -DLILYGO_T_PANEL
+ -D LILYGO_T_PANEL=1
+ ;-DARDUINO_USB_CDC_ON_BOOT
+ ;-DUSE_USB_CDC_CONSOLE
+
+;region -- ArduinoGFX build options ------------------------
+ -D HASP_USE_ARDUINOGFX=1
+ -D HASP_LV_USE_SW_ROTATE=1
+ -D ST7701_DRIVER=1
+ -D TFT_WIDTH=480
+ -D TFT_HEIGHT=480
+ ; Bus Settings
+ -D TFT_HSYNC=39
+ -D TFT_VSYNC=40
+ -D TFT_PCLK=41
+ -D TFT_B0=1
+ -D TFT_B1=2
+ -D TFT_B2=3
+ -D TFT_B3=4
+ -D TFT_B4=5
+ -D TFT_G0=6
+ -D TFT_G1=7
+ -D TFT_G2=8
+ -D TFT_G3=9
+ -D TFT_G4=10
+ -D TFT_G5=11
+ -D TFT_R0=12
+ -D TFT_R1=13
+ -D TFT_R2=42
+ -D TFT_R3=46
+ -D TFT_R4=45
+ -D TFT_BCKL=14
+
+
+ -D TFT_HSYNC_POLARITY=1
+ -D TFT_HSYNC_FRONT_PORCH=10
+ -D TFT_HSYNC_PULSE_WIDTH=8
+ -D TFT_HSYNC_BACK_PORCH=50
+ -D TFT_VSYNC_POLARITY=1
+ -D TFT_VSYNC_FRONT_PORCH=10
+ -D TFT_VSYNC_PULSE_WIDTH=8
+ -D TFT_VSYNC_BACK_PORCH=20
+ -D TFT_PCLK_ACTIVE_NEG=1
+ -D TFT_PREFER_SPEED=12000000
+ -D TFT_AUTO_FLUSH=1
+ ; Touch Settings
+ -D TOUCH_WIDTH=480
+ -D TOUCH_HEIGHT=480
+ -D TOUCH_SDA=17
+ -D TOUCH_SCL=18
+ -D TOUCH_INT=21
+ -D TOUCH_RST=4
+ -D TOUCH_CS=-1
+ -D TOUCH_DRIVER=0x3240
+ ; -D TOUCH_IRQ=-1
+ ; -D I2C_TOUCH_FREQUENCY=400000
+ ; -D I2C_TOUCH_ADDRESS=0x48
+ ; -D I2C_TOUCH_PORT=1
+
+;endregion
+
+lib_deps =
+ ${arduino_esp32s3_v2.lib_deps}
+; moononournation/GFX Library for Arduino@1.4.0 ; Update needs modification of custom PCA class ; ${ft6336.lib_deps}
+; ; git+https://github.com/admarschoonen/TouchLib.git
+ ; moononournation/GFX Library for Arduino@1.4.0 ;
+[env:lilygo-t-panel_16MB]
+extends = lilygo-t-panel, flash_16mb
+monitor_port = COM8
+upload_port = COM8
From f61f0bdfa5da5dfb4106ec0898d56f870362bd2f Mon Sep 17 00:00:00 2001
From: Shubham Sharma <10323297+shubham-vunet@users.noreply.github.com>
Date: Wed, 2 Oct 2024 22:28:51 +0530
Subject: [PATCH 091/142] Fix code
---
src/drv/tft/tft_driver_arduinogfx.cpp | 4 ----
user_setups/esp32s3/lilygo-t-panel.ini | 22 +++++-----------------
2 files changed, 5 insertions(+), 21 deletions(-)
diff --git a/src/drv/tft/tft_driver_arduinogfx.cpp b/src/drv/tft/tft_driver_arduinogfx.cpp
index 5c80d750..be22c08e 100644
--- a/src/drv/tft/tft_driver_arduinogfx.cpp
+++ b/src/drv/tft/tft_driver_arduinogfx.cpp
@@ -26,10 +26,6 @@ void ArduinoGfx::init(int w, int h)
LOG_TRACE(TAG_TFT, F(D_SERVICE_STARTING));
#if(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(LILYGO_T_PANEL)
-
- // pinMode(TFT_SCLK, OUTPUT);
- // pinMode(TFT_MOSI, OUTPUT);
- // pinMode(TFT_MISO, OUTPUT);
Arduino_DataBus* bus = new Arduino_XL9535SWSPI(17 /* SDA */, 18 /* SCL */, -1 /* XL PWD */, 17 /* XL CS */,
15 /* XL SCK */, 16 /* XL MOSI */);
Arduino_ESP32RGBPanel *rgbpanel = new Arduino_ESP32RGBPanel(
diff --git a/user_setups/esp32s3/lilygo-t-panel.ini b/user_setups/esp32s3/lilygo-t-panel.ini
index d0f4868e..54d5f600 100644
--- a/user_setups/esp32s3/lilygo-t-panel.ini
+++ b/user_setups/esp32s3/lilygo-t-panel.ini
@@ -2,7 +2,7 @@
; Lilygo T-Panel S3, 4-Inch Touch Screen ;
; - Custom esp32-s3 board ;
; - st7701s TFT ;
-; - CST3240 touch controller ;
+; - CST3240 touch controller (WIP) ;
; - IO Expansion: XL9535 ;
;***************************************************;
@@ -48,18 +48,6 @@ build_flags =
-D TFT_R4=45
-D TFT_BCKL=14
-
- -D TFT_HSYNC_POLARITY=1
- -D TFT_HSYNC_FRONT_PORCH=10
- -D TFT_HSYNC_PULSE_WIDTH=8
- -D TFT_HSYNC_BACK_PORCH=50
- -D TFT_VSYNC_POLARITY=1
- -D TFT_VSYNC_FRONT_PORCH=10
- -D TFT_VSYNC_PULSE_WIDTH=8
- -D TFT_VSYNC_BACK_PORCH=20
- -D TFT_PCLK_ACTIVE_NEG=1
- -D TFT_PREFER_SPEED=12000000
- -D TFT_AUTO_FLUSH=1
; Touch Settings
-D TOUCH_WIDTH=480
-D TOUCH_HEIGHT=480
@@ -69,10 +57,10 @@ build_flags =
-D TOUCH_RST=4
-D TOUCH_CS=-1
-D TOUCH_DRIVER=0x3240
- ; -D TOUCH_IRQ=-1
- ; -D I2C_TOUCH_FREQUENCY=400000
- ; -D I2C_TOUCH_ADDRESS=0x48
- ; -D I2C_TOUCH_PORT=1
+ ; -D TOUCH_IRQ=
+ ; -D I2C_TOUCH_FREQUENCY=
+ ; -D I2C_TOUCH_ADDRESS=
+ ; -D I2C_TOUCH_PORT=
;endregion
From b55efe007d5bc6fba4b97111d928aad3b0087656 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Sat, 5 Oct 2024 00:51:03 +0200
Subject: [PATCH 092/142] Add Lanbon L9 for testing
---
src/drv/tft/tft_driver_arduinogfx.cpp | 13 ++++-
user_setups/esp32s3/lanbon_l9.ini | 68 +++++++++++++++++++++++++++
2 files changed, 80 insertions(+), 1 deletion(-)
create mode 100644 user_setups/esp32s3/lanbon_l9.ini
diff --git a/src/drv/tft/tft_driver_arduinogfx.cpp b/src/drv/tft/tft_driver_arduinogfx.cpp
index ae73d504..c8eb8961 100644
--- a/src/drv/tft/tft_driver_arduinogfx.cpp
+++ b/src/drv/tft/tft_driver_arduinogfx.cpp
@@ -25,7 +25,18 @@ void ArduinoGfx::init(int w, int h)
{
LOG_TRACE(TAG_TFT, F(D_SERVICE_STARTING));
-#if(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(LILYGO_T_RGB)
+#if(TFT_WIDTH == 170) && (TFT_HEIGHT == 320)
+ Arduino_DataBus *bus = new Arduino_ESP32PAR8Q(
+ TFT_DC, TFT_CS, TFT_WR, TFT_RD,
+ TFT_D0, TFT_D1, TFT_D2, TFT_D3, TFT_D4, TFT_D5, TFT_D6, TFT_D7);
+ Arduino_GFX *gfx = new Arduino_ST7789(bus,
+ TFT_RST /* RST */, TFT_ROTATION /* rotation */, true /* IPS */,
+ TFT_WIDTH /* width */, TFT_HEIGHT /* height */,
+ 35 /* col offset 1 */, 0 /* row offset 1 */,
+ 35 /* col offset 2 */, 0 /* row offset 2 */
+ );
+
+#elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(LILYGO_T_RGB)
Wire.begin(8 /* SDA */, 48 /* SCL */, 800000L /* speed */);
Arduino_DataBus* bus = new Arduino_XL9535SWSPI(8 /* SDA */, 48 /* SCL */, 2 /* XL PWD */, 3 /* XL CS */,
5 /* XL SCK */, 4 /* XL MOSI */);
diff --git a/user_setups/esp32s3/lanbon_l9.ini b/user_setups/esp32s3/lanbon_l9.ini
new file mode 100644
index 00000000..9dfb0616
--- /dev/null
+++ b/user_setups/esp32s3/lanbon_l9.ini
@@ -0,0 +1,68 @@
+;***************************************************;
+; Lanbon L9 with ST7789 ;
+;***************************************************;
+
+[env:lanbon_l9]
+extends = arduino_esp32s3_v2, flash_16mb
+board = esp32-s3-devkitc-1
+board_build.arduino.memory_type = qio_opi
+
+build_flags =
+ ${env.build_flags}
+ ${esp32s3.build_flags}
+ ${esp32s3.ps_ram}
+ -D HASP_MODEL="Lanbon L9"
+ ;-D ARDUINO_USB_MODE=0
+ ;-DARDUINO_USB_CDC_ON_BOOT
+ ;-DUSE_USB_CDC_CONSOLE
+
+;region -- TFT_eSPI build options ------------------------
+ -D ST7789_DRIVER=1
+ -D HASP_USE_ARDUINOGFX=1
+ -D TFT_WIDTH=170
+ -D TFT_HEIGHT=320
+ -D TFT_ROTATION=0 ; see TFT_ROTATION values
+ ; -D TFT_INVERSION_OFF ; for normal colors
+ ;-D TFT_INVERSION_ON
+ ;-D TFT_RGB_ORDER=0 ; Colour order Blue-Green-Red
+ ;-D INVERT_COLORS=1 ; for inverted colors
+
+ -D TFT_RST=-1
+ -D TFT_CS=21
+ -D TFT_DC=17
+ -D TFT_WR=13
+ -D TFT_RD=18
+ -D TFT_D0=6
+ -D TFT_D1=7
+ -D TFT_D2=15
+ -D TFT_D3=16
+ -D TFT_D4=10
+ -D TFT_D5=9
+ -D TFT_D6=46
+ -D TFT_D7=3
+ -D TFT_BCKL=42
+ ; Touch Setttings
+ -D TOUCH_WIDTH=170
+ -D TOUCH_HEIGHT=320
+ -D TOUCH_DRIVER=0x911
+ -D TOUCH_SCL=0
+ -D TOUCH_SDA=35
+ -D TOUCH_IRQ=-1
+ -D TOUCH_RST=-1
+ -D I2C_TOUCH_ADDRESS=0x5d ; or 0x14
+ -D I2C_TOUCH_FREQUENCY=400000
+;endregion
+
+;region -- Library options -------------------------------
+lib_deps =
+ ${env.lib_deps}
+ ${esp32s3.lib_deps}
+ ${arduino_esp32s3_v2.lib_deps}
+ ${arduinogfx.lib_deps}
+ ${goodix.lib_deps}
+
+lib_ignore =
+ ${env.lib_ignore}
+ ${esp32s3.lib_ignore}
+ ${arduino_esp32s3_v2.lib_ignore}
+;endregion
\ No newline at end of file
From 31a1272c5ea809aa975143b5316215b21d0facd7 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Tue, 8 Oct 2024 20:00:41 +0200
Subject: [PATCH 093/142] Fix dropdown text when show_selected=0
---
src/hasp/hasp_attribute.cpp | 1 +
src/hasp/hasp_attribute_helper.h | 25 +++++++++++++++++++++++++
src/hasp/hasp_event.cpp | 8 ++++++--
src/hasp/hasp_object.cpp | 1 +
4 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/src/hasp/hasp_attribute.cpp b/src/hasp/hasp_attribute.cpp
index b8b42eca..7bba5ed4 100644
--- a/src/hasp/hasp_attribute.cpp
+++ b/src/hasp/hasp_attribute.cpp
@@ -1751,6 +1751,7 @@ static hasp_attribute_type_t attribute_common_text(lv_obj_t* obj, uint16_t attr_
{LV_HASP_LABEL, ATTR_TEXT, my_label_set_text, my_label_get_text},
{LV_HASP_LABEL, ATTR_TEMPLATE, my_obj_set_template, my_obj_get_template},
{LV_HASP_CHECKBOX, ATTR_TEXT, lv_checkbox_set_text, lv_checkbox_get_text},
+ {LV_HASP_DROPDOWN, ATTR_TEXT, my_dropdown_set_text, my_dropdown_get_text},
{LV_HASP_TABVIEW, ATTR_TEXT, my_tabview_set_text, my_tabview_get_text},
{LV_HASP_TEXTAREA, ATTR_TEXT, lv_textarea_set_text, lv_textarea_get_text},
{LV_HASP_TAB, ATTR_TEXT, my_tab_set_text, my_tab_get_text},
diff --git a/src/hasp/hasp_attribute_helper.h b/src/hasp/hasp_attribute_helper.h
index a88e716f..b900182b 100644
--- a/src/hasp/hasp_attribute_helper.h
+++ b/src/hasp/hasp_attribute_helper.h
@@ -472,6 +472,31 @@ lv_obj_t* FindButtonLabel(lv_obj_t* btn)
return NULL;
}
+// OK - lvgl does not return a const char *
+static const char* my_dropdown_get_text(const lv_obj_t* dd)
+{
+ const char* str_p = lv_dropdown_get_text((lv_obj_t*)dd);
+ return str_p ? str_p : "";
+}
+
+// OK - lvgl does not return a const char *
+static void my_dropdown_set_text(lv_obj_t* dd, const char* text)
+{
+ size_t len = 0;
+ if(text) len = strlen(text) + 1;
+
+ // release previous text
+ char* str_p = (char*)lv_dropdown_get_text(dd);
+ if(str_p) lv_mem_free(str_p);
+
+ // reserve and copy new text
+ str_p = (char*)lv_mem_alloc(len);
+ if(str_p != NULL) strncpy(str_p, text, len);
+
+ lv_dropdown_set_text((lv_obj_t*)dd, str_p); // library does not return const
+ lv_obj_invalidate(dd); // Needed if old ptr is equal to new ptr
+}
+
// OK - lvgl does not return a const char *
static const char* my_label_get_text(const lv_obj_t* label)
{
diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp
index 051a65c8..ed801f8b 100644
--- a/src/hasp/hasp_event.cpp
+++ b/src/hasp/hasp_event.cpp
@@ -99,6 +99,10 @@ void delete_event_handler(lv_obj_t* obj, lv_event_t event)
my_obj_del_task(obj);
break;
+ case LV_HASP_DROPDOWN:
+ lv_mem_free(lv_dropdown_get_text(obj));
+ break;
+
default:
break;
}
@@ -302,8 +306,8 @@ static void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16
char eventname[8];
Parser::get_event_name(eventid, eventname, sizeof(eventname));
if(const char* tag = my_obj_get_tag(obj))
- snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":%s,\"tag\":%s}"), eventname,
- val, serialized_text, tag);
+ snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":%s,\"tag\":%s}"), eventname, val,
+ serialized_text, tag);
else
snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d,\"text\":%s}"), eventname, val,
serialized_text);
diff --git a/src/hasp/hasp_object.cpp b/src/hasp/hasp_object.cpp
index a28d7946..2bf787e0 100644
--- a/src/hasp/hasp_object.cpp
+++ b/src/hasp/hasp_object.cpp
@@ -640,6 +640,7 @@ void hasp_new_object(const JsonObject& config, uint8_t& saved_page_id)
case HASP_OBJ_DROPDOWN:
obj = lv_dropdown_create(parent_obj, NULL);
if(obj) {
+ lv_dropdown_set_text(obj, NULL); // Clear default text
lv_dropdown_set_draw_arrow(obj, true);
// lv_dropdown_set_anim_time(obj, 200);
lv_obj_set_top(obj, true);
From e42b27f67aae765e1b7edd2a0ef375d33f8775f0 Mon Sep 17 00:00:00 2001
From: fvanroie
Date: Tue, 8 Oct 2024 22:35:01 +0200
Subject: [PATCH 094/142] LV_MEM_CUSTOM default allocators use PSram when
available #810
---
include/lv_conf_v7.h | 4 ++--
include/lv_conf_v8.h | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/lv_conf_v7.h b/include/lv_conf_v7.h
index 606203cc..20ad2966 100644
--- a/include/lv_conf_v7.h
+++ b/include/lv_conf_v7.h
@@ -116,8 +116,8 @@ typedef int16_t lv_coord_t;
# define LV_MEM_AUTO_DEFRAG 1
#else /*LV_MEM_CUSTOM*/
#define LV_MEM_CUSTOM_INCLUDE /*Header for the dynamic memory function*/
-#define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/
-#define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
+#define LV_MEM_CUSTOM_ALLOC hasp_malloc /*Wrapper to malloc*/
+#define LV_MEM_CUSTOM_FREE hasp_free /*Wrapper to free*/
#endif /*LV_MEM_CUSTOM*/
#ifndef LV_VDB_SIZE
diff --git a/include/lv_conf_v8.h b/include/lv_conf_v8.h
index 494982d7..78bfb3ed 100644
--- a/include/lv_conf_v8.h
+++ b/include/lv_conf_v8.h
@@ -105,8 +105,8 @@ typedef int16_t lv_coord_t;
# define LV_MEM_AUTO_DEFRAG 1
#else /*LV_MEM_CUSTOM*/
# define LV_MEM_CUSTOM_INCLUDE /*Header for the dynamic memory function*/
-# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/
-# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
+# define LV_MEM_CUSTOM_ALLOC hasp_malloc /*Wrapper to malloc*/
+# define LV_MEM_CUSTOM_FREE hasp_free /*Wrapper to free*/
#endif /*LV_MEM_CUSTOM*/
/* Use the standard memcpy and memset instead of LVGL's own functions.
From 735b4a170b6b7c7b39b484138d05fab6bf0e6950 Mon Sep 17 00:00:00 2001
From: Lars Michelsen
Date: Fri, 11 Oct 2024 21:07:58 +0200
Subject: [PATCH 095/142] Fix support for Adafruit HUZZAH32 V2 ESP32
Featherwing 3.5 V2
* The board of "env:huzzah32-v2-featherwing-35-v2" was changed to
adafruit_feather_esp32_v2
Previously it was pointing to the v1 board. See also:
V1: https://github.com/platformio/platform-espressif32/blob/develop/boards/featheresp32.json
V2: https://github.com/platformio/platform-espressif32/blob/develop/boards/adafruit_feather_esp32_v2.json
* Fixed the port numbers
* hasp_gpio_type_t::BUTTON had to be renamed because adafruit_feather_esp32_v2/pins_arduino.h
defines a macro named BUTTON.
---
src/sys/gpio/hasp_gpio.cpp | 14 +++++++-------
src/sys/gpio/hasp_gpio.h | 4 ++--
src/sys/svc/hasp_http.cpp | 4 ++--
src/sys/svc/hasp_http_async.cpp | 6 +++---
.../esp32/huzzah32-v2-featherwing-35-v2.ini | 17 +++++++++--------
5 files changed, 23 insertions(+), 22 deletions(-)
diff --git a/src/sys/gpio/hasp_gpio.cpp b/src/sys/gpio/hasp_gpio.cpp
index 693eec7b..52b60a96 100644
--- a/src/sys/gpio/hasp_gpio.cpp
+++ b/src/sys/gpio/hasp_gpio.cpp
@@ -123,7 +123,7 @@ static void gpio_event_handler(AceButton* button, uint8_t eventType, uint8_t but
bool state = false;
switch(eventType) {
case AceButton::kEventPressed:
- if(gpioConfig[btnid].type != hasp_gpio_type_t::BUTTON) {
+ if(gpioConfig[btnid].type != hasp_gpio_type_t::BUTTON_TYPE) {
eventid = HASP_EVENT_ON;
} else {
eventid = HASP_EVENT_DOWN;
@@ -146,7 +146,7 @@ static void gpio_event_handler(AceButton* button, uint8_t eventType, uint8_t but
// state = true; // do not repeat DOWN + LONG + HOLD
// break;
case AceButton::kEventReleased:
- if(gpioConfig[btnid].type != hasp_gpio_type_t::BUTTON) {
+ if(gpioConfig[btnid].type != hasp_gpio_type_t::BUTTON_TYPE) {
eventid = HASP_EVENT_OFF;
} else {
eventid = HASP_EVENT_RELEASE;
@@ -253,7 +253,7 @@ static void gpio_setup_pin(uint8_t index)
pinMode(gpio->pin, input_mode);
gpio->max = 0;
break;
- case hasp_gpio_type_t::BUTTON:
+ case hasp_gpio_type_t::BUTTON_TYPE:
if(gpio->btn) delete gpio->btn;
gpio->btn = new AceButton(&buttonConfig, gpio->pin, default_state, index);
gpio->power = gpio->btn->isPressedRaw();
@@ -849,7 +849,7 @@ void gpio_discovery(JsonObject& input, JsonArray& relay, JsonArray& light, JsonA
relay.add(gpioConfig[i].pin);
break;
- case BUTTON ... TOUCH:
+ case BUTTON_TYPE ... TOUCH:
event.add(gpioConfig[i].pin);
break;
@@ -861,7 +861,7 @@ void gpio_discovery(JsonObject& input, JsonArray& relay, JsonArray& light, JsonA
dimmer.add(gpioConfig[i].pin);
break;
- // case BUTTON ... TOUCH:
+ // case BUTTON_TYPE ... TOUCH:
case SWITCH:
strcpy_P(description, PSTR("none"));
break;
@@ -955,7 +955,7 @@ void gpio_discovery(JsonObject& input, JsonArray& relay, JsonArray& light, JsonA
}
if((gpioConfig[i].type >= hasp_gpio_type_t::SWITCH && gpioConfig[i].type <= hasp_gpio_type_t::WINDOW)) {
- // || (gpioConfig[i].type >= hasp_gpio_type_t::BUTTON && gpioConfig[i].type <= hasp_gpio_type_t::TOUCH)) {
+ // || (gpioConfig[i].type >= hasp_gpio_type_t::BUTTON_TYPE && gpioConfig[i].type <= hasp_gpio_type_t::TOUCH)) {
JsonArray arr = input[description];
if(arr.isNull()) arr = input.createNestedArray(description);
arr.add(gpioConfig[i].pin);
@@ -1040,4 +1040,4 @@ bool gpioSetConfig(const JsonObject& settings)
return changed;
}
-#endif // HASP_USE_CONFIG
\ No newline at end of file
+#endif // HASP_USE_CONFIG
diff --git a/src/sys/gpio/hasp_gpio.h b/src/sys/gpio/hasp_gpio.h
index 105f4460..559bc762 100644
--- a/src/sys/gpio/hasp_gpio.h
+++ b/src/sys/gpio/hasp_gpio.h
@@ -134,7 +134,7 @@ enum hasp_gpio_type_t {
TAMPER = 0xBB,
UPDATE = 0xBC,
- BUTTON = 0xF0,
+ BUTTON_TYPE = 0xF0,
BUTTON_TOGGLE_UP = 0xF1,
BUTTON_TOGGLE_DOWN = 0xF2,
BUTTON_TOGGLE_BOTH = 0xF3,
@@ -153,4 +153,4 @@ enum hasp_gpio_type_t {
} /* extern "C" */
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp
index eba778bb..06af58d8 100644
--- a/src/sys/svc/hasp_http.cpp
+++ b/src/sys/svc/hasp_http.cpp
@@ -1804,7 +1804,7 @@ static void webHandleGpioConfig()
switch(conf.type) {
- case hasp_gpio_type_t::BUTTON:
+ case hasp_gpio_type_t::BUTTON_TYPE:
httpMessage += D_GPIO_BUTTON;
break;
case hasp_gpio_type_t::SWITCH:
@@ -2049,7 +2049,7 @@ static void webHandleGpioInput()
httpMessage += F("
");
httpMessage += F("Type