From d61cc2d13056442e3f3d977c0b0dcdfa7dfdcdf9 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Thu, 21 Jul 2016 12:25:20 +0300 Subject: [PATCH] Implement sending content from progmem make the example editor run from progmem --- README.md | 95 ++++- .../ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino | 376 +++++++++++++++--- examples/ESP_AsyncFSBrowser/data/edit.htm.gz | Bin 4116 -> 0 bytes examples/ESP_AsyncFSBrowser/data/graphs.js.gz | Bin 2379 -> 0 bytes examples/ESP_AsyncFSBrowser/data/index.htm | 33 +- src/ESPAsyncWebServer.h | 4 + src/WebRequest.cpp | 16 + src/WebResponseImpl.h | 9 + src/WebResponses.cpp | 21 + 9 files changed, 477 insertions(+), 77 deletions(-) delete mode 100644 examples/ESP_AsyncFSBrowser/data/edit.htm.gz delete mode 100644 examples/ESP_AsyncFSBrowser/data/graphs.js.gz diff --git a/README.md b/README.md index 64ef012..6134dad 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,79 @@ response->addHeader("Server","ESP Async Web Server"); request->send(response); ``` +### Send large webpage from PROGMEM +```cpp +const char index_html[] PROGMEM = "..."; // large char array, tested with 14k +request->send_P(200, "text/html", index_html); +``` + +### Send large webpage from PROGMEM and extra headers +```cpp +const char index_html[] PROGMEM = "..."; // large char array, tested with 14k +AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", index_html); +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +### Send binary content from PROGMEM +```cpp + +//File: favicon.ico.gz, Size: 726 +#define favicon_ico_gz_len 726 +const uint8_t favicon_ico_gz[] PROGMEM = { + 0x1F, 0x8B, 0x08, 0x08, 0x0B, 0x87, 0x90, 0x57, 0x00, 0x03, 0x66, 0x61, 0x76, 0x69, 0x63, 0x6F, + 0x6E, 0x2E, 0x69, 0x63, 0x6F, 0x00, 0xCD, 0x53, 0x5F, 0x48, 0x9A, 0x51, 0x14, 0xBF, 0x62, 0x6D, + 0x86, 0x96, 0xA9, 0x64, 0xD3, 0xFE, 0xA8, 0x99, 0x65, 0x1A, 0xB4, 0x8A, 0xA8, 0x51, 0x54, 0x23, + 0xA8, 0x11, 0x49, 0x51, 0x8A, 0x34, 0x62, 0x93, 0x85, 0x31, 0x58, 0x44, 0x12, 0x45, 0x2D, 0x58, + 0xF5, 0x52, 0x41, 0x10, 0x23, 0x82, 0xA0, 0x20, 0x98, 0x2F, 0xC1, 0x26, 0xED, 0xA1, 0x20, 0x89, + 0x04, 0xD7, 0x83, 0x58, 0x20, 0x28, 0x04, 0xAB, 0xD1, 0x9B, 0x8C, 0xE5, 0xC3, 0x60, 0x32, 0x64, + 0x0E, 0x56, 0xBF, 0x9D, 0xEF, 0xF6, 0x30, 0x82, 0xED, 0xAD, 0x87, 0xDD, 0x8F, 0xF3, 0xDD, 0x8F, + 0x73, 0xCF, 0xEF, 0x9C, 0xDF, 0x39, 0xBF, 0xFB, 0x31, 0x26, 0xA2, 0x27, 0x37, 0x97, 0xD1, 0x5B, + 0xCF, 0x9E, 0x67, 0x30, 0xA6, 0x66, 0x8C, 0x99, 0xC9, 0xC8, 0x45, 0x9E, 0x6B, 0x3F, 0x5F, 0x74, + 0xA6, 0x94, 0x5E, 0xDB, 0xFF, 0xB2, 0xE6, 0xE7, 0xE7, 0xF9, 0xDE, 0xD6, 0xD6, 0x96, 0xDB, 0xD8, + 0xD8, 0x78, 0xBF, 0xA1, 0xA1, 0xC1, 0xDA, 0xDC, 0xDC, 0x2C, 0xEB, 0xED, 0xED, 0x15, 0x9B, 0xCD, + 0xE6, 0x4A, 0x83, 0xC1, 0xE0, 0x2E, 0x29, 0x29, 0x99, 0xD6, 0x6A, 0xB5, 0x4F, 0x75, 0x3A, 0x9D, + 0x61, 0x75, 0x75, 0x95, 0xB5, 0xB7, 0xB7, 0xDF, 0xC8, 0xD1, 0xD4, 0xD4, 0xF4, 0xB0, 0xBA, 0xBA, + 0xFA, 0x83, 0xD5, 0x6A, 0xFD, 0x5A, 0x5E, 0x5E, 0x9E, 0x28, 0x2D, 0x2D, 0x0D, 0x10, 0xC6, 0x4B, + 0x98, 0x78, 0x5E, 0x5E, 0xDE, 0x95, 0x42, 0xA1, 0x40, 0x4E, 0x4E, 0xCE, 0x65, 0x76, 0x76, 0xF6, + 0x47, 0xB5, 0x5A, 0x6D, 0x4F, 0x26, 0x93, 0xA2, 0xD6, 0xD6, 0x56, 0x8E, 0x6D, 0x69, 0x69, 0xD1, + 0x11, 0x36, 0x62, 0xB1, 0x58, 0x60, 0x32, 0x99, 0xA0, 0xD7, 0xEB, 0x51, 0x58, 0x58, 0x88, 0xFC, + 0xFC, 0x7C, 0x10, 0x16, 0x02, 0x56, 0x2E, 0x97, 0x43, 0x2A, 0x95, 0x42, 0x2C, 0x16, 0x23, 0x33, + 0x33, 0x33, 0xAE, 0x52, 0xA9, 0x1E, 0x64, 0x65, 0x65, 0x71, 0x7C, 0x7D, 0x7D, 0xBD, 0x93, 0xEA, + 0xFE, 0x30, 0x1A, 0x8D, 0xE8, 0xEC, 0xEC, 0xC4, 0xE2, 0xE2, 0x22, 0x6A, 0x6A, 0x6A, 0x40, 0x39, + 0x41, 0xB5, 0x38, 0x4E, 0xC8, 0x33, 0x3C, 0x3C, 0x0C, 0x87, 0xC3, 0xC1, 0x6B, 0x54, 0x54, 0x54, + 0xBC, 0xE9, 0xEB, 0xEB, 0x93, 0x5F, 0x5C, 0x5C, 0x30, 0x8A, 0x9D, 0x2E, 0x2B, 0x2B, 0xBB, 0xA2, + 0x3E, 0x41, 0xBD, 0x21, 0x1E, 0x8F, 0x63, 0x6A, 0x6A, 0x0A, 0x81, 0x40, 0x00, 0x94, 0x1B, 0x3D, + 0x3D, 0x3D, 0x42, 0x3C, 0x96, 0x96, 0x96, 0x70, 0x7E, 0x7E, 0x8E, 0xE3, 0xE3, 0x63, 0xF8, 0xFD, + 0xFE, 0xB4, 0xD7, 0xEB, 0xF5, 0x8F, 0x8F, 0x8F, 0x5B, 0x68, 0x5E, 0x6F, 0x05, 0xCE, 0xB4, 0xE3, + 0xE8, 0xE8, 0x08, 0x27, 0x27, 0x27, 0xD8, 0xDF, 0xDF, 0xC7, 0xD9, 0xD9, 0x19, 0x6C, 0x36, 0x1B, + 0x36, 0x36, 0x36, 0x38, 0x9F, 0x85, 0x85, 0x05, 0xAC, 0xAF, 0xAF, 0x23, 0x1A, 0x8D, 0x22, 0x91, + 0x48, 0x20, 0x16, 0x8B, 0xFD, 0xDA, 0xDA, 0xDA, 0x7A, 0x41, 0x33, 0x7E, 0x57, 0x50, 0x50, 0x80, + 0x89, 0x89, 0x09, 0x84, 0xC3, 0x61, 0x6C, 0x6F, 0x6F, 0x23, 0x12, 0x89, 0xE0, 0xE0, 0xE0, 0x00, + 0x43, 0x43, 0x43, 0x58, 0x5E, 0x5E, 0xE6, 0x9C, 0x7D, 0x3E, 0x1F, 0x46, 0x47, 0x47, 0x79, 0xBE, + 0xBD, 0xBD, 0x3D, 0xE1, 0x3C, 0x1D, 0x0C, 0x06, 0x9F, 0x10, 0xB7, 0xC7, 0x84, 0x4F, 0xF6, 0xF7, + 0xF7, 0x63, 0x60, 0x60, 0x00, 0x83, 0x83, 0x83, 0x18, 0x19, 0x19, 0xC1, 0xDC, 0xDC, 0x1C, 0x8F, + 0x17, 0x7C, 0xA4, 0x27, 0xE7, 0x34, 0x39, 0x39, 0x89, 0x9D, 0x9D, 0x1D, 0x6E, 0x54, 0xE3, 0x13, + 0xE5, 0x34, 0x11, 0x37, 0x49, 0x51, 0x51, 0xD1, 0x4B, 0xA5, 0x52, 0xF9, 0x45, 0x26, 0x93, 0x5D, + 0x0A, 0xF3, 0x92, 0x48, 0x24, 0xA0, 0x6F, 0x14, 0x17, 0x17, 0xA3, 0xB6, 0xB6, 0x16, 0x5D, 0x5D, + 0x5D, 0x7C, 0x1E, 0xBB, 0xBB, 0xBB, 0x9C, 0xD7, 0xE1, 0xE1, 0x21, 0x42, 0xA1, 0xD0, 0x6B, 0xD2, + 0x45, 0x4C, 0x33, 0x12, 0x34, 0xCC, 0xA0, 0x19, 0x54, 0x92, 0x56, 0x0E, 0xD2, 0xD9, 0x43, 0xF8, + 0xCF, 0x82, 0x56, 0xC2, 0xDC, 0xEB, 0xEA, 0xEA, 0x38, 0x7E, 0x6C, 0x6C, 0x4C, 0xE0, 0xFE, 0x9D, + 0xB8, 0xBF, 0xA7, 0xFA, 0xAF, 0x56, 0x56, 0x56, 0xEE, 0x6D, 0x6E, 0x6E, 0xDE, 0xB8, 0x47, 0x55, + 0x55, 0x55, 0x6C, 0x66, 0x66, 0x46, 0x44, 0xDA, 0x3B, 0x34, 0x1A, 0x4D, 0x94, 0xB0, 0x3F, 0x09, + 0x7B, 0x45, 0xBD, 0xA5, 0x5D, 0x2E, 0x57, 0x8C, 0x7A, 0x73, 0xD9, 0xED, 0xF6, 0x3B, 0x84, 0xFF, + 0xE7, 0x7D, 0xA6, 0x3A, 0x2C, 0x95, 0x4A, 0xB1, 0x8E, 0x8E, 0x0E, 0x6D, 0x77, 0x77, 0xB7, 0xCD, + 0xE9, 0x74, 0x3E, 0x73, 0xBB, 0xDD, 0x8F, 0x3C, 0x1E, 0x8F, 0xE6, 0xF4, 0xF4, 0x94, 0xAD, 0xAD, + 0xAD, 0xDD, 0xDE, 0xCF, 0x73, 0x0B, 0x0B, 0xB8, 0xB6, 0xE0, 0x5D, 0xC6, 0x66, 0xC5, 0xE4, 0x10, + 0x4C, 0xF4, 0xF7, 0xD8, 0x59, 0xF2, 0x7F, 0xA3, 0xB8, 0xB4, 0xFC, 0x0F, 0xEE, 0x37, 0x70, 0xEC, + 0x16, 0x4A, 0x7E, 0x04, 0x00, 0x00 +}; + +AsyncWebServerResponse *response = request->beginResponse_P(200, "image/x-icon", favicon_ico_gz, favicon_ico_gz_len); +response->addHeader("Content-Encoding", "gzip"); +request->send(response); +``` + ### Respond with content coming from a Stream ```cpp //read 12 bytes from Serial and send them as Content Type text/plain @@ -369,28 +442,6 @@ response->print(""); request->send(response); ``` -### Send a large webpage from PROGMEM using callback response -Example provided by [@nouser2013](https://github.com/nouser2013) -```cpp -const char indexhtml[] PROGMEM = "..."; // large char array, tested with 5k -AsyncWebServerResponse *response = request->beginResponse( - String("text/html"), - strlen_P(indexhtml), - [](uint8_t *buffer, size_t maxLen, size_t alreadySent) -> size_t { - if (strlen_P(indexhtml+alreadySent)>maxLen) { - // We have more to read than fits in maxLen Buffer - memcpy_P((char*)buffer, indexhtml+alreadySent, maxLen); - return maxLen; - } - // Ok, last chunk - memcpy_P((char*)buffer, indexhtml+alreadySent, strlen_P(indexhtml+alreadySent)); - return strlen_P(indexhtml+alreadySent); // Return from here to end of indexhtml - } -); -response->addHeader("Server", "MyServerString"); -request->send(response); -``` - ### ArduinoJson Basic Response This way of sending Json is great for when the result is below 4KB ```cpp diff --git a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino b/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino index ba0ba6b..8d357fc 100644 --- a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino +++ b/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino @@ -7,19 +7,286 @@ #include // WEB HANDLER IMPLEMENTATION + + +//File: edit.htm.gz, Size: 4143 +#define edit_htm_gz_len 4143 +const uint8_t edit_htm_gz[] PROGMEM = { + 0x1F, 0x8B, 0x08, 0x08, 0xAE, 0x92, 0x90, 0x57, 0x00, 0x03, 0x65, 0x64, 0x69, 0x74, 0x2E, 0x68, + 0x74, 0x6D, 0x00, 0xCD, 0x1B, 0x7B, 0x5F, 0xDB, 0xC8, 0xF1, 0x7F, 0x3E, 0x85, 0x4E, 0x69, 0x6B, + 0xB9, 0x7E, 0x13, 0xC2, 0x25, 0x06, 0x93, 0xDA, 0xC6, 0x04, 0xC2, 0x1B, 0xDB, 0xC9, 0x41, 0x4A, + 0xFB, 0x5B, 0x4B, 0x6B, 0x5B, 0xA0, 0xD7, 0x49, 0x32, 0x36, 0x49, 0xF9, 0xEE, 0x9D, 0xD9, 0x5D, + 0x49, 0x2B, 0x59, 0x76, 0x20, 0x77, 0xD7, 0x5E, 0x1E, 0x48, 0xDA, 0x9D, 0x99, 0x9D, 0xD7, 0xCE, + 0xCC, 0x3E, 0xD8, 0xFD, 0x69, 0xFF, 0xBC, 0x3B, 0xB8, 0xBE, 0xE8, 0x29, 0xD3, 0xD0, 0xB6, 0xF6, + 0x36, 0x76, 0xF1, 0xA1, 0x58, 0xC4, 0x99, 0xB4, 0x54, 0xEA, 0xA8, 0xD8, 0x40, 0x89, 0x01, 0x8F, + 0xD0, 0x0C, 0x2D, 0xBA, 0xD7, 0xEB, 0x5F, 0x28, 0x3D, 0xC3, 0x0C, 0x5D, 0x7F, 0xB7, 0xC6, 0x5B, + 0x36, 0x76, 0x83, 0xF0, 0xD1, 0xA2, 0x4A, 0xF8, 0xE8, 0xD1, 0x96, 0x1A, 0xD2, 0x45, 0x58, 0xD3, + 0x83, 0x40, 0x55, 0x6C, 0x6A, 0x98, 0xA4, 0xA5, 0x06, 0xBA, 0x4F, 0x19, 0x9D, 0xAA, 0x6E, 0x2B, + 0xDF, 0x36, 0x14, 0xE5, 0x6B, 0xC5, 0x74, 0x0C, 0xBA, 0x68, 0x2A, 0xAF, 0xEB, 0xF5, 0x1D, 0xF8, + 0xF6, 0xDC, 0xC0, 0x0C, 0x4D, 0xD7, 0x69, 0x2A, 0x64, 0x14, 0xB8, 0xD6, 0x2C, 0xA4, 0xD8, 0x6A, + 0xD1, 0x71, 0xD8, 0x54, 0xDE, 0x78, 0x0B, 0xFC, 0x18, 0xB9, 0xBE, 0x41, 0xFD, 0xA6, 0xD2, 0xF0, + 0x16, 0x0A, 0x80, 0x98, 0x86, 0xF2, 0x6A, 0x6B, 0x6B, 0x8B, 0xF5, 0x10, 0xFD, 0x7E, 0xE2, 0xBB, + 0x33, 0xC7, 0xA8, 0xE8, 0xAE, 0xE5, 0x02, 0xCC, 0xAB, 0x83, 0x37, 0xF8, 0x17, 0x3B, 0x0D, 0x33, + 0xF0, 0x2C, 0xF2, 0xD8, 0x54, 0x1C, 0xD7, 0xA1, 0x9C, 0xCE, 0xA2, 0x12, 0x4C, 0x89, 0xE1, 0xCE, + 0x9B, 0x4A, 0x1D, 0xFE, 0x36, 0xEA, 0x40, 0xD0, 0x9F, 0x8C, 0x88, 0xA6, 0xD4, 0xCB, 0xE2, 0x5F, + 0x75, 0x4B, 0x29, 0x22, 0xEC, 0xD8, 0x75, 0xC2, 0x4A, 0x60, 0x7E, 0xA5, 0x30, 0xEC, 0x26, 0x67, + 0x83, 0x35, 0x8D, 0x89, 0x6D, 0x5A, 0x40, 0x33, 0x20, 0x4E, 0x50, 0x09, 0xA8, 0x6F, 0x8E, 0xE3, + 0xAE, 0x39, 0x35, 0x27, 0xD3, 0xB0, 0x39, 0x72, 0x2D, 0x63, 0x67, 0xE3, 0x89, 0x09, 0x3C, 0xB3, + 0x98, 0xCC, 0x96, 0x19, 0x00, 0x31, 0x54, 0x53, 0xC2, 0x4C, 0xE8, 0x7A, 0xC0, 0x45, 0x22, 0x2B, + 0x7B, 0xB5, 0x89, 0x3F, 0x31, 0x1D, 0xF1, 0xE1, 0x11, 0xC3, 0x30, 0x9D, 0x09, 0xFB, 0xE2, 0xE4, + 0x2C, 0x93, 0x91, 0x4B, 0x54, 0xE6, 0x53, 0x8B, 0x84, 0xE6, 0x03, 0x23, 0x68, 0x9B, 0x4E, 0x65, + 0x6E, 0x1A, 0xE1, 0xB4, 0xA9, 0x6C, 0xD7, 0x39, 0xC7, 0xFA, 0xCC, 0x0F, 0x50, 0x29, 0x9E, 0x6B, + 0x3A, 0x21, 0xF5, 0x23, 0x32, 0x81, 0x47, 0x1C, 0x46, 0x28, 0xD2, 0x99, 0xD0, 0x66, 0xAC, 0x30, + 0xD3, 0xB1, 0x4C, 0x87, 0x56, 0x46, 0x96, 0xAB, 0xDF, 0xA7, 0x38, 0xD9, 0x46, 0xBA, 0x11, 0x2F, + 0xCD, 0xA9, 0xFB, 0x40, 0x7D, 0xE5, 0x9B, 0x64, 0x05, 0x41, 0x4B, 0xC9, 0x80, 0xF0, 0x01, 0xE3, + 0xE1, 0x7A, 0xBD, 0x1E, 0x03, 0x09, 0x1F, 0x66, 0xA0, 0x21, 0xD0, 0x39, 0xBE, 0x44, 0xB2, 0x49, + 0x42, 0x67, 0xF4, 0xB1, 0xAC, 0x45, 0x41, 0xC3, 0x74, 0xBC, 0x59, 0x98, 0xD1, 0x8C, 0xEC, 0x4C, + 0xAE, 0x47, 0x74, 0x33, 0x7C, 0x8C, 0x14, 0x89, 0x28, 0xDF, 0x84, 0xD1, 0x90, 0x92, 0x6F, 0x13, + 0x8B, 0x19, 0x59, 0xF9, 0x44, 0x7D, 0x83, 0x38, 0xA4, 0xAC, 0xB4, 0x7D, 0x93, 0x00, 0x63, 0xFD, + 0x94, 0x91, 0x2B, 0xB6, 0xFB, 0xB5, 0x32, 0x83, 0x4F, 0x68, 0xB2, 0xA8, 0x1E, 0x26, 0xB6, 0x04, + 0xD3, 0x8F, 0xEE, 0xCD, 0x30, 0xBF, 0x33, 0xB7, 0x31, 0xA3, 0x79, 0xA6, 0xEE, 0x29, 0xF7, 0x1F, + 0xA5, 0x11, 0x69, 0x19, 0x19, 0x8D, 0x6D, 0xC5, 0x55, 0x51, 0x19, 0xB9, 0x61, 0xE8, 0xDA, 0x4D, + 0x31, 0x33, 0x12, 0x6D, 0x71, 0x87, 0x7E, 0xBB, 0xC2, 0xEE, 0x6B, 0x6C, 0x9B, 0x1E, 0x55, 0x51, + 0xC0, 0x5E, 0xA1, 0xA9, 0x13, 0xAB, 0x42, 0x2C, 0x73, 0x02, 0x8A, 0xB4, 0x4D, 0xC3, 0xB0, 0x68, + 0x7A, 0xB2, 0x35, 0x95, 0x99, 0x6F, 0x69, 0x05, 0x83, 0x84, 0xA4, 0x69, 0xDA, 0x64, 0x42, 0x6B, + 0x9E, 0x33, 0xD9, 0x19, 0x91, 0x80, 0x6E, 0x6F, 0x95, 0xCD, 0x4F, 0x9D, 0xF3, 0xAB, 0x79, 0xFD, + 0xF8, 0xC3, 0xC4, 0x6D, 0xC3, 0x9F, 0xB3, 0xFE, 0x70, 0xDA, 0x1B, 0x4E, 0xE0, 0xAD, 0x83, 0x9F, + 0xED, 0xCB, 0x6E, 0xFB, 0x12, 0x1E, 0xDD, 0x46, 0xE9, 0x6E, 0xFC, 0x2B, 0x36, 0x74, 0x3E, 0x18, + 0x9D, 0xC1, 0xB0, 0xD7, 0x6E, 0x1F, 0xD7, 0x8E, 0xCE, 0xE6, 0x9F, 0x8F, 0xB7, 0xB1, 0xBB, 0x63, + 0xD5, 0xAF, 0x3E, 0x4D, 0xEB, 0xC3, 0xCD, 0x77, 0xB6, 0x71, 0x68, 0x4C, 0x75, 0x7B, 0xD8, 0xBE, + 0xFC, 0x7C, 0xF5, 0x70, 0x6D, 0x0F, 0x27, 0xFD, 0xCF, 0x8D, 0xE9, 0xCD, 0xE6, 0xA7, 0xFE, 0xCD, + 0xE7, 0x83, 0x7B, 0xFA, 0xCB, 0xE1, 0xC7, 0x9B, 0xC1, 0x1C, 0x10, 0xF6, 0xDD, 0xFE, 0xF0, 0xAA, + 0xF3, 0xA9, 0x33, 0xB9, 0xE9, 0xE8, 0xBD, 0xC5, 0xC8, 0x3A, 0xEB, 0x7C, 0x68, 0x8F, 0xDA, 0x9B, + 0x3A, 0xA5, 0x93, 0xC1, 0x55, 0x67, 0x76, 0x74, 0x7C, 0x3E, 0x31, 0xCD, 0x69, 0xFF, 0xE6, 0x6C, + 0xA0, 0x77, 0xDF, 0x9C, 0x0C, 0x0F, 0xDB, 0xE6, 0xF4, 0xEC, 0xE3, 0x55, 0xFD, 0xFE, 0xC3, 0x71, + 0x77, 0x5F, 0xBF, 0xFE, 0x78, 0xBD, 0xBD, 0xFF, 0xBA, 0xF6, 0xF3, 0xCF, 0xA7, 0xC6, 0xB9, 0xE9, + 0x0C, 0x1E, 0xBE, 0xB6, 0x27, 0xDD, 0xF9, 0xDB, 0xC7, 0x60, 0x30, 0x3D, 0x7A, 0x70, 0x6A, 0x9F, + 0xDC, 0xBB, 0xA3, 0xC7, 0x53, 0xF8, 0x7F, 0x71, 0x51, 0x1A, 0xF5, 0x1B, 0xC1, 0xF0, 0xF2, 0xE8, + 0xD3, 0x66, 0xF0, 0xEE, 0x8D, 0xD7, 0xD9, 0xDF, 0x7F, 0xB0, 0x47, 0x17, 0x35, 0xDB, 0xB8, 0x1F, + 0x87, 0x6F, 0x5F, 0x87, 0xDE, 0xF5, 0x64, 0x76, 0xF3, 0xEB, 0x9B, 0x8F, 0xD3, 0xDA, 0x39, 0x25, + 0xD7, 0xD3, 0xD2, 0xE3, 0xD7, 0xC7, 0xB7, 0xD3, 0xC1, 0xE1, 0xC3, 0x99, 0x45, 0x16, 0x67, 0x67, + 0xFA, 0x57, 0xBB, 0x64, 0x91, 0x77, 0xE7, 0x03, 0x8B, 0xF8, 0x8D, 0xA1, 0xD1, 0xAE, 0x95, 0xBA, + 0x9B, 0xED, 0xAD, 0xD0, 0xBF, 0xEA, 0x3A, 0xFB, 0xAF, 0xEF, 0xFA, 0x6F, 0x3B, 0x9D, 0x86, 0x3B, + 0xFA, 0x75, 0xF3, 0xC3, 0xFD, 0xF6, 0x87, 0xE1, 0xF6, 0xE5, 0xE8, 0xB2, 0xDD, 0xDF, 0xEA, 0x0C, + 0xC9, 0x75, 0xFF, 0xB2, 0x3D, 0xDE, 0x1A, 0x4D, 0xA7, 0xC7, 0xC7, 0x83, 0x03, 0xA3, 0xFD, 0xD5, + 0x6F, 0x9F, 0xCF, 0xDB, 0x8B, 0xDE, 0xB0, 0x7D, 0x58, 0x3A, 0xEE, 0x9D, 0xD6, 0x1B, 0xFD, 0xEB, + 0xD7, 0x93, 0xD3, 0xED, 0x79, 0x27, 0xE8, 0xB5, 0x2F, 0x3B, 0xF5, 0xC9, 0xC7, 0x92, 0x4D, 0x6E, + 0xDC, 0xEE, 0xEB, 0xC9, 0xD1, 0xB6, 0x79, 0x71, 0x4D, 0xDA, 0x47, 0x9D, 0x8F, 0x81, 0x79, 0x65, + 0x1F, 0x0E, 0xEB, 0xED, 0xF6, 0xC9, 0x39, 0x3D, 0xE8, 0xBE, 0x26, 0xC7, 0x9B, 0xFA, 0x67, 0xD0, + 0xFF, 0xF0, 0x17, 0xFA, 0x73, 0xA9, 0x3D, 0x3F, 0xAF, 0x5B, 0xFA, 0x3B, 0x3A, 0x38, 0xBC, 0x1E, + 0x30, 0xEB, 0xF4, 0xAC, 0x83, 0xC1, 0x7D, 0x7F, 0x76, 0x69, 0x77, 0xBB, 0x85, 0x22, 0x78, 0x6B, + 0xC5, 0xA7, 0x1E, 0x25, 0x61, 0x26, 0xD6, 0x26, 0xD3, 0x0C, 0x23, 0x68, 0x3D, 0xE3, 0xAE, 0x51, + 0x5C, 0xC0, 0x20, 0x07, 0xE9, 0xA0, 0x62, 0x50, 0xDD, 0xF5, 0x09, 0x87, 0x07, 0x6C, 0xEA, 0xA3, + 0x03, 0x22, 0xC6, 0x3F, 0x58, 0x8E, 0x50, 0x78, 0x8A, 0x50, 0x88, 0x63, 0x28, 0x5A, 0x34, 0x93, + 0x30, 0x98, 0x19, 0xF4, 0xC1, 0xD4, 0x69, 0xC5, 0x33, 0x17, 0xD4, 0xAA, 0x30, 0x02, 0xCD, 0x7A, + 0x11, 0xA9, 0xE2, 0x48, 0xF8, 0x4C, 0x26, 0x1E, 0x71, 0xC0, 0x0D, 0xF9, 0x08, 0x51, 0x8B, 0x71, + 0x47, 0x74, 0x0A, 0x51, 0x19, 0x26, 0x9E, 0x8D, 0x4F, 0x3E, 0x03, 0x5D, 0xBF, 0x32, 0x9A, 0x4D, + 0xC6, 0xE6, 0x02, 0xE6, 0xC1, 0xD8, 0x74, 0xCC, 0x90, 0x2A, 0x8D, 0x00, 0xA5, 0x7B, 0xDA, 0x80, + 0x1F, 0xFF, 0x88, 0xE8, 0xDD, 0xD3, 0xC7, 0xB1, 0x4F, 0x6C, 0x1A, 0x3C, 0x9B, 0x1C, 0xE7, 0x67, + 0xEC, 0xBB, 0x90, 0xE5, 0x14, 0xF6, 0x9E, 0x8D, 0x65, 0x30, 0x06, 0xEF, 0x08, 0xDD, 0x35, 0x20, + 0x8C, 0x95, 0xA7, 0x8D, 0x57, 0x33, 0xCF, 0x72, 0x89, 0xC1, 0xC2, 0xEB, 0xCA, 0xB8, 0x96, 0xA4, + 0x10, 0x9F, 0xCF, 0xE1, 0x6C, 0x3A, 0x11, 0x73, 0x7B, 0x53, 0x84, 0x85, 0x54, 0x94, 0xD9, 0xDC, + 0x4A, 0x85, 0x90, 0x0A, 0x47, 0x6B, 0x88, 0xCC, 0x91, 0x93, 0x58, 0x45, 0xA8, 0xE2, 0x9F, 0x2C, + 0x86, 0x23, 0x9F, 0x21, 0xD8, 0xEE, 0xBB, 0x3C, 0x46, 0x0C, 0x88, 0xE0, 0xB5, 0xC4, 0x27, 0x4F, + 0x5B, 0x8D, 0x28, 0x6D, 0xC5, 0x4A, 0x79, 0xCB, 0x3D, 0xEB, 0x15, 0x65, 0x15, 0x47, 0x59, 0x79, + 0xE5, 0xF9, 0xE0, 0x13, 0x74, 0xFE, 0xEC, 0x01, 0x65, 0xBD, 0xE4, 0x0C, 0x1E, 0x8F, 0xC8, 0x2B, + 0x0C, 0xAE, 0x03, 0xA9, 0xCA, 0x88, 0x84, 0x8C, 0x87, 0xCD, 0xD7, 0x0C, 0x03, 0x4B, 0xD8, 0x7E, + 0xC3, 0xB9, 0xDE, 0xAD, 0xB1, 0x5C, 0x85, 0x05, 0x92, 0xEE, 0x9B, 0x5E, 0xB8, 0xB7, 0x31, 0x9E, + 0x39, 0x3A, 0x32, 0xAC, 0x80, 0xC3, 0x93, 0x90, 0x1E, 0x98, 0x16, 0x1D, 0x0A, 0x33, 0x6B, 0xC2, + 0xAF, 0xCA, 0x0A, 0x2A, 0xB4, 0xAC, 0x70, 0x89, 0x99, 0xB7, 0x3F, 0x10, 0x5F, 0x59, 0xD8, 0xD6, + 0x61, 0x18, 0x7A, 0x3B, 0xE2, 0x93, 0x27, 0xBC, 0x96, 0x62, 0xB8, 0xFA, 0x0C, 0xB1, 0xAA, 0x9C, + 0x60, 0x8F, 0xD3, 0xD0, 0x54, 0xD6, 0xAF, 0xB2, 0x3A, 0x86, 0xBD, 0x56, 0xB1, 0x38, 0x03, 0x78, + 0x75, 0x0C, 0x43, 0xAA, 0x49, 0xB3, 0x3D, 0xB3, 0x42, 0xD3, 0xB3, 0xB0, 0x6B, 0x4C, 0xAC, 0x80, + 0x26, 0x3D, 0x0E, 0x38, 0x3F, 0x22, 0x60, 0x88, 0x67, 0x08, 0xF1, 0x50, 0x13, 0x1A, 0x8A, 0x71, + 0x3A, 0x8F, 0x47, 0x46, 0xC4, 0x77, 0xB1, 0x4A, 0x3C, 0x8F, 0x3A, 0x46, 0x77, 0x6A, 0x5A, 0x86, + 0xC6, 0x68, 0x14, 0x23, 0x6E, 0x3D, 0x12, 0x4E, 0x9F, 0xC7, 0x2C, 0x42, 0x56, 0x41, 0xF1, 0x30, + 0x30, 0xF7, 0xFF, 0x0A, 0xB6, 0xA8, 0x71, 0x57, 0x24, 0x06, 0x86, 0x95, 0xA4, 0x35, 0xE2, 0x35, + 0x0D, 0x6B, 0xD0, 0x31, 0x01, 0xF1, 0x3E, 0x11, 0x6B, 0xC6, 0x7A, 0x6B, 0x2F, 0x17, 0x03, 0xE9, + 0xC4, 0x52, 0x8C, 0x66, 0xE0, 0x3E, 0xCE, 0x1A, 0x39, 0x38, 0x00, 0x17, 0x84, 0xBF, 0x57, 0x4D, + 0xC7, 0xA1, 0xFE, 0xE1, 0xE0, 0xF4, 0x04, 0xD0, 0x0A, 0xDC, 0xD4, 0x85, 0x17, 0x73, 0xC1, 0x69, + 0xC5, 0x7C, 0xD8, 0xF7, 0x68, 0xC4, 0x67, 0xF2, 0xC1, 0x81, 0xD3, 0x7C, 0x74, 0x19, 0xF8, 0xCB, + 0xF9, 0xE0, 0xB4, 0x80, 0x2C, 0x96, 0x4E, 0x91, 0x27, 0x4F, 0xC1, 0x2B, 0x2F, 0xDC, 0x20, 0xBC, + 0xF0, 0x5D, 0x9D, 0x06, 0xC1, 0x15, 0xFD, 0x75, 0x46, 0x83, 0x50, 0x2B, 0xF2, 0x70, 0x68, 0x8E, + 0x15, 0x4D, 0xB8, 0x6E, 0x15, 0x46, 0x35, 0x1E, 0xFB, 0x21, 0x0C, 0xAD, 0xB4, 0x5A, 0xCA, 0x96, + 0x80, 0x40, 0x98, 0x18, 0x24, 0x80, 0xDE, 0x59, 0xA0, 0xFC, 0xD4, 0x52, 0x36, 0xEB, 0xF5, 0xA2, + 0x42, 0x2C, 0x28, 0x45, 0x34, 0xB5, 0x77, 0x75, 0x75, 0x7E, 0xF5, 0x45, 0x2D, 0xA5, 0xA1, 0x4A, + 0xEA, 0x6D, 0x53, 0x49, 0x1A, 0x7D, 0x1A, 0x78, 0xAE, 0x13, 0xD0, 0x01, 0x78, 0x46, 0x71, 0x47, + 0x90, 0xA6, 0xE0, 0xD2, 0x4A, 0x34, 0x8E, 0xC2, 0x66, 0x16, 0x00, 0x8E, 0x01, 0x76, 0x7A, 0x01, + 0xA6, 0x65, 0xF6, 0xAD, 0x3E, 0xA0, 0x83, 0xC4, 0x28, 0x4F, 0x52, 0x14, 0x96, 0xC4, 0xE4, 0x2A, + 0xE6, 0x48, 0x82, 0x73, 0x31, 0x32, 0x68, 0xD4, 0x81, 0xC8, 0xF0, 0xCB, 0xE9, 0x09, 0x7E, 0xC5, + 0xF2, 0xEF, 0xC8, 0x30, 0x55, 0xD7, 0x61, 0xD2, 0x23, 0xE7, 0x54, 0x9F, 0xC2, 0xDA, 0x0A, 0xED, + 0x97, 0xAF, 0x3A, 0x8E, 0x88, 0x86, 0x1E, 0x43, 0x61, 0xBA, 0x0F, 0xD3, 0x4F, 0x8C, 0x70, 0x20, + 0x3E, 0x23, 0xDA, 0x51, 0xB7, 0xB0, 0x91, 0xC6, 0xDD, 0xBF, 0xAC, 0x78, 0xD9, 0xB1, 0xA1, 0x57, + 0x53, 0x2F, 0x86, 0x03, 0xE8, 0x53, 0x6B, 0x18, 0x57, 0xD4, 0x0C, 0x44, 0x80, 0xE8, 0x11, 0xB9, + 0xE2, 0x8E, 0x90, 0x3D, 0xF1, 0x1E, 0xD7, 0xD1, 0x2D, 0x53, 0xBF, 0xC7, 0x20, 0x21, 0xF4, 0xA1, + 0xD1, 0xD8, 0xC0, 0x92, 0x12, 0xAB, 0x6C, 0x61, 0x77, 0x3E, 0xD6, 0xD4, 0xAA, 0x5A, 0x04, 0x23, + 0xB7, 0x94, 0x4A, 0xA3, 0x08, 0x4B, 0x94, 0x70, 0xE6, 0x3B, 0x7C, 0x44, 0x59, 0x8D, 0x59, 0xDD, + 0xF3, 0x88, 0x57, 0xC5, 0x39, 0x32, 0x84, 0xE2, 0x32, 0xD3, 0xFF, 0x24, 0xCD, 0xAA, 0xF5, 0xFC, + 0xF0, 0xF8, 0x85, 0x8C, 0x07, 0x55, 0x8B, 0x3A, 0x13, 0x8C, 0x3D, 0xC0, 0x4A, 0x3D, 0x76, 0x38, + 0x99, 0xA1, 0xA7, 0x3F, 0xA7, 0x29, 0x59, 0xD4, 0x2D, 0x2B, 0x92, 0x28, 0x5F, 0xEA, 0xB7, 0x65, + 0x65, 0x49, 0x67, 0x19, 0x1B, 0x9F, 0xF7, 0x5F, 0x64, 0xE4, 0x24, 0xDA, 0x83, 0x46, 0x23, 0x51, + 0x5E, 0xA4, 0xD2, 0x94, 0x2E, 0x99, 0xA0, 0x00, 0x23, 0xC2, 0x71, 0x9A, 0x79, 0x16, 0xA4, 0x13, + 0x38, 0x98, 0xA5, 0x00, 0x52, 0xD3, 0xDE, 0x37, 0xFF, 0x59, 0xD5, 0xBE, 0xFC, 0xAB, 0x7A, 0x5B, + 0x2A, 0x16, 0xDF, 0xFF, 0xA5, 0x56, 0xA5, 0x0B, 0xAA, 0x6B, 0x11, 0x91, 0xE2, 0x97, 0xC6, 0x6D, + 0x82, 0x22, 0xC8, 0xD6, 0xB4, 0xEA, 0xDF, 0x8B, 0xFF, 0xAC, 0x32, 0x9C, 0xD5, 0x08, 0xC0, 0x34, + 0xE6, 0x0A, 0x77, 0xCC, 0xD1, 0x7E, 0x02, 0x6E, 0xB1, 0xF2, 0x84, 0x8A, 0x8F, 0x1A, 0xB1, 0x23, + 0x48, 0xCC, 0x26, 0xDC, 0x3D, 0x65, 0xF0, 0x91, 0xD3, 0x7C, 0x74, 0x80, 0x61, 0x62, 0x40, 0xA7, + 0x8A, 0x9B, 0x26, 0xE0, 0xF3, 0x5C, 0x2C, 0xFC, 0x52, 0x53, 0x31, 0x48, 0x06, 0xBD, 0xF3, 0xE8, + 0x24, 0x01, 0xBD, 0xF3, 0x26, 0x31, 0xA8, 0xC4, 0x4F, 0xFC, 0x5A, 0x52, 0x60, 0x32, 0xC1, 0x4F, + 0x00, 0xCF, 0xF0, 0x97, 0x38, 0x03, 0xA7, 0x5B, 0x53, 0x95, 0xFF, 0xFC, 0x47, 0x72, 0x91, 0xAA, + 0x45, 0x82, 0xF0, 0x28, 0x9A, 0x91, 0x35, 0x31, 0x23, 0x93, 0x69, 0x20, 0xE3, 0x23, 0x76, 0x29, + 0x1A, 0x33, 0xAA, 0x55, 0x53, 0xD1, 0x33, 0x05, 0x2D, 0x0D, 0x12, 0xCC, 0x46, 0x41, 0xE8, 0x43, + 0xD5, 0xA3, 0xD5, 0xCB, 0xEB, 0x06, 0x2F, 0x35, 0x8A, 0xD9, 0x01, 0xB8, 0x0B, 0x42, 0xDD, 0x9D, + 0x89, 0xB2, 0x03, 0x08, 0xD3, 0x49, 0x39, 0x94, 0x29, 0x84, 0xA2, 0x4A, 0xAC, 0xB5, 0x32, 0x77, + 0xA9, 0x02, 0x44, 0x8D, 0x33, 0x26, 0xC6, 0xFD, 0x2B, 0xD7, 0x5D, 0x57, 0x30, 0x19, 0xE6, 0x03, + 0x87, 0x8F, 0x60, 0xAB, 0x3A, 0x48, 0x10, 0x9C, 0x89, 0xCA, 0x02, 0xD6, 0x1B, 0x2F, 0xAF, 0x1E, + 0x22, 0x52, 0x99, 0x8C, 0x89, 0x01, 0x6E, 0xDF, 0x9D, 0x3B, 0xF8, 0xE4, 0x15, 0x06, 0xD7, 0xF1, + 0x2A, 0xDA, 0x05, 0x43, 0x00, 0x57, 0xD8, 0x8A, 0xA4, 0x50, 0xAC, 0x06, 0xBE, 0x2E, 0x8C, 0x50, + 0x52, 0xDF, 0x47, 0xBD, 0xAD, 0xD0, 0x9F, 0xF1, 0xD2, 0xEE, 0x69, 0x69, 0xB8, 0x0B, 0xAE, 0x91, + 0xE7, 0x8C, 0xA6, 0x72, 0x7D, 0xAB, 0x30, 0x0A, 0x16, 0xAF, 0x55, 0xB1, 0x6D, 0x80, 0x4A, 0xC0, + 0xAD, 0x0B, 0xE1, 0xAB, 0x42, 0xC5, 0xCB, 0x30, 0x6C, 0x57, 0x21, 0x03, 0x94, 0x2A, 0x3E, 0x76, + 0x4D, 0x7B, 0xA2, 0x80, 0x00, 0x2D, 0xB5, 0x50, 0x62, 0x12, 0x14, 0xDE, 0xFF, 0x5B, 0x1F, 0xB5, + 0x0A, 0x25, 0x08, 0x4B, 0xB4, 0xEA, 0xB8, 0x73, 0xAD, 0x58, 0x2A, 0xA8, 0x0A, 0x23, 0xDC, 0x52, + 0x6D, 0xB2, 0x10, 0x5B, 0x5A, 0x8D, 0x7A, 0xFD, 0xAF, 0x3B, 0x0A, 0x7E, 0x8B, 0xF5, 0x4B, 0xD4, + 0xC0, 0xF6, 0x87, 0xC8, 0x2C, 0x74, 0x77, 0xE2, 0x2D, 0x0E, 0xBE, 0xB5, 0xA1, 0x2A, 0xB5, 0xBD, + 0xC2, 0xB2, 0x3E, 0xC0, 0x09, 0x2D, 0x2C, 0xBC, 0x4F, 0xA9, 0x33, 0x03, 0xBB, 0x71, 0xA7, 0x15, + 0x4A, 0x41, 0x67, 0xC1, 0x4D, 0xA6, 0x35, 0x8E, 0x32, 0xB3, 0xA2, 0xC0, 0x4A, 0xAD, 0x94, 0xB5, + 0x11, 0xAF, 0x98, 0x44, 0x2B, 0xC2, 0x47, 0x5B, 0x4D, 0xC8, 0x32, 0x23, 0x42, 0x88, 0x99, 0x22, + 0xC5, 0x71, 0x8B, 0x71, 0x24, 0x33, 0x03, 0xAC, 0x6A, 0x90, 0x69, 0x6E, 0xC1, 0x78, 0x0A, 0x73, + 0xC0, 0x94, 0x82, 0xD5, 0x5D, 0x5C, 0x81, 0xEF, 0xE1, 0x16, 0x2D, 0xAC, 0x3F, 0xF0, 0x35, 0x0E, + 0x2F, 0x02, 0x7A, 0x4D, 0xF6, 0x5C, 0x91, 0x86, 0xE3, 0xE2, 0x88, 0x71, 0x13, 0x0B, 0x34, 0x72, + 0x8D, 0x47, 0xC9, 0x7D, 0x82, 0xCE, 0x63, 0x37, 0x9A, 0x33, 0x5A, 0x41, 0xB7, 0xC1, 0x51, 0x45, + 0xAE, 0xD8, 0xC3, 0x4C, 0x91, 0x46, 0xF3, 0xA9, 0xED, 0x3E, 0x50, 0x2E, 0x2E, 0xB5, 0x92, 0xEA, + 0x2B, 0x15, 0x7B, 0x98, 0xE8, 0x47, 0xB8, 0xBD, 0xF4, 0x22, 0xD9, 0x85, 0xB7, 0xFF, 0x98, 0xF8, + 0x4B, 0xD3, 0xE5, 0x7F, 0x2E, 0x7B, 0xEC, 0x42, 0xD1, 0xCC, 0xFE, 0x31, 0x27, 0x8A, 0xB0, 0x45, + 0x7F, 0xF4, 0x99, 0xA7, 0xB0, 0x28, 0x1A, 0xA5, 0x35, 0x16, 0x63, 0xAC, 0xD5, 0xD8, 0x72, 0x34, + 0x8B, 0xE4, 0xF9, 0x43, 0xD5, 0xF5, 0x94, 0xCC, 0x34, 0x83, 0xB2, 0xF9, 0xFC, 0x83, 0x5A, 0xE2, + 0xC8, 0x91, 0x92, 0xF8, 0x57, 0xAE, 0x8E, 0x20, 0xC4, 0x87, 0x34, 0xA3, 0x21, 0x01, 0xBE, 0x56, + 0x41, 0x58, 0x1A, 0x72, 0xE4, 0xFF, 0xB5, 0x7A, 0xD2, 0x71, 0x2F, 0x98, 0xBA, 0xF3, 0xAE, 0xEB, + 0xE0, 0xCA, 0x99, 0x87, 0xBE, 0x07, 0x96, 0x5E, 0x91, 0x27, 0x28, 0x34, 0x03, 0xB6, 0xB4, 0x4B, + 0xA2, 0x20, 0xE4, 0x43, 0x01, 0xFC, 0x9C, 0xA4, 0xC9, 0x71, 0x02, 0xDD, 0x77, 0x2D, 0x6B, 0xE0, + 0x7A, 0x32, 0x0A, 0xE3, 0x31, 0xE9, 0x79, 0xBF, 0xB2, 0xA7, 0x99, 0xF4, 0x44, 0x2F, 0x62, 0xA0, + 0x04, 0x28, 0x3B, 0xD6, 0x09, 0x1D, 0x87, 0x2B, 0x06, 0x63, 0x5D, 0xF9, 0xA3, 0xB1, 0xAE, 0xEF, + 0x0E, 0x87, 0x50, 0xC9, 0x78, 0x16, 0x1F, 0x89, 0x29, 0x0D, 0x4A, 0x03, 0x13, 0x1E, 0xBF, 0x40, + 0x55, 0x96, 0x07, 0x1A, 0x32, 0x05, 0xC8, 0x90, 0xD7, 0x31, 0x64, 0x2C, 0x43, 0xA2, 0xDF, 0x54, + 0xA1, 0x81, 0xC6, 0x5E, 0x02, 0xC8, 0x26, 0xD9, 0x02, 0xCB, 0x6F, 0xAB, 0xE0, 0x04, 0xA7, 0xEC, + 0x51, 0x52, 0x0A, 0xDE, 0x62, 0x15, 0x20, 0xE7, 0x13, 0x7F, 0xCA, 0x60, 0xA9, 0xF4, 0x98, 0xE0, + 0x88, 0x34, 0x19, 0x45, 0x06, 0x59, 0xA9, 0xA9, 0xE9, 0x14, 0x23, 0x48, 0x7E, 0xC1, 0x12, 0x38, + 0x9A, 0x29, 0xE1, 0xC0, 0x1D, 0x8F, 0x03, 0x1A, 0x7E, 0xC6, 0x8E, 0x04, 0x8E, 0x27, 0xF6, 0x3C, + 0xC0, 0x43, 0xD6, 0xB3, 0x24, 0x87, 0xEB, 0xD8, 0xEE, 0x2C, 0xA0, 0x2E, 0xDB, 0x0A, 0xCB, 0x99, + 0x7A, 0x58, 0x75, 0xC7, 0xC6, 0xDA, 0xE5, 0x2A, 0x81, 0x12, 0x39, 0x69, 0xDB, 0x53, 0x34, 0xA1, + 0x27, 0xC6, 0x63, 0x51, 0xEE, 0xBD, 0x06, 0x0C, 0x54, 0x4E, 0xAA, 0x09, 0x10, 0xB8, 0xC2, 0x38, + 0xAF, 0x45, 0x29, 0x71, 0xFC, 0x11, 0xF3, 0x79, 0x49, 0x9D, 0xF1, 0xFE, 0xC4, 0xF2, 0xFC, 0x4E, + 0x6A, 0xE7, 0x13, 0x4A, 0xF8, 0xEA, 0xA0, 0xCC, 0x96, 0x35, 0x65, 0x05, 0x4F, 0x31, 0xE5, 0x0A, + 0x07, 0xFA, 0x9F, 0x17, 0x2D, 0x01, 0x90, 0xEF, 0xC6, 0x69, 0x9A, 0xC6, 0x37, 0xF1, 0xD8, 0x4A, + 0xA1, 0xF8, 0x5E, 0x55, 0x9B, 0xCC, 0x1F, 0x4A, 0xB8, 0x6E, 0x60, 0x2B, 0x2F, 0x69, 0xAA, 0x90, + 0x11, 0xB5, 0xD6, 0xD0, 0xC7, 0x08, 0x1A, 0x8F, 0x80, 0xB0, 0xA9, 0x70, 0x9B, 0xAC, 0x0F, 0xD8, + 0xE8, 0xA9, 0x0A, 0x0B, 0x81, 0x65, 0xD6, 0xD6, 0xC6, 0xDD, 0x74, 0xDD, 0x24, 0x44, 0x01, 0xA7, + 0x3F, 0x71, 0xE7, 0xD4, 0xEF, 0x92, 0x80, 0x6A, 0xC5, 0xE2, 0xEA, 0xB2, 0x47, 0xC0, 0x27, 0x6A, + 0xCF, 0xAD, 0x48, 0xBE, 0x4B, 0x55, 0xAE, 0x26, 0x96, 0x48, 0xCA, 0x89, 0x2C, 0x92, 0x87, 0x5B, + 0x1B, 0x14, 0x35, 0xCB, 0x97, 0x8A, 0x56, 0xB1, 0xAA, 0x06, 0x3D, 0xEE, 0xF3, 0xDD, 0x4D, 0x2D, + 0x26, 0x07, 0x4B, 0x31, 0x70, 0xCD, 0x0B, 0xDF, 0xF5, 0xC8, 0x84, 0x9D, 0x84, 0x24, 0x5D, 0x4B, + 0xA1, 0xBF, 0x1C, 0x99, 0x16, 0x77, 0x9B, 0xE3, 0xCD, 0x04, 0xC1, 0x0A, 0x5F, 0xD2, 0x33, 0x88, + 0x65, 0x2F, 0x23, 0x86, 0x71, 0x02, 0x39, 0x14, 0xBC, 0xC1, 0x97, 0xD3, 0x47, 0x48, 0xED, 0xE0, + 0x47, 0x6A, 0x68, 0x4E, 0x66, 0x5D, 0x1D, 0x6D, 0xA1, 0x2B, 0x31, 0xFA, 0x62, 0xCE, 0xC4, 0x3B, + 0x26, 0x1A, 0xDB, 0x08, 0x87, 0xDE, 0xFA, 0x0E, 0x3C, 0x60, 0x7A, 0x5B, 0xF0, 0x2C, 0x95, 0x52, + 0x0E, 0x80, 0x78, 0x5F, 0xCC, 0x5B, 0xB1, 0x6F, 0xDC, 0x8A, 0x36, 0xC0, 0x8B, 0x89, 0x81, 0xB2, + 0x05, 0x41, 0xEE, 0x34, 0x8A, 0xE9, 0xF0, 0xF9, 0x14, 0x7F, 0xB2, 0x89, 0x15, 0x69, 0x6F, 0x63, + 0x49, 0x59, 0xD9, 0xBA, 0x3D, 0x51, 0xD0, 0xDA, 0xED, 0x0F, 0x06, 0x9B, 0xB3, 0x93, 0xB1, 0x7A, + 0x27, 0x22, 0x98, 0x9B, 0xA1, 0x3E, 0xC5, 0x2D, 0x06, 0xC9, 0xF7, 0x74, 0xF0, 0x46, 0x58, 0xB9, + 0x2E, 0x42, 0xB5, 0x99, 0x69, 0xC3, 0xED, 0x89, 0x9C, 0x36, 0x6B, 0xA9, 0xF1, 0x2E, 0x58, 0x6A, + 0xD2, 0x97, 0x5B, 0x3C, 0x6F, 0xB9, 0x2D, 0x58, 0xC6, 0x5C, 0xA4, 0x06, 0x88, 0xFD, 0x0C, 0x1D, + 0x70, 0x79, 0xF3, 0x35, 0xEE, 0x8E, 0x8F, 0x25, 0xB2, 0xAA, 0xCD, 0xAC, 0x0B, 0xFE, 0x1F, 0xBA, + 0xF5, 0x9C, 0xC9, 0xB2, 0xCA, 0xBC, 0xE5, 0xB6, 0x89, 0x39, 0xFE, 0xCD, 0x92, 0x87, 0x53, 0x33, + 0x90, 0xF7, 0xAE, 0xE5, 0xF0, 0x20, 0x29, 0x20, 0xDE, 0xBE, 0x90, 0xD3, 0x48, 0xB2, 0xA7, 0x81, + 0x9F, 0x67, 0xAE, 0xC1, 0x76, 0xE4, 0x84, 0xDF, 0x62, 0x7D, 0xFA, 0x81, 0x86, 0x31, 0x50, 0x99, + 0x45, 0x78, 0xB1, 0x3F, 0x28, 0xAB, 0x1C, 0xAA, 0xDD, 0xEE, 0x48, 0x1E, 0x2B, 0xE2, 0x33, 0x62, + 0x43, 0x9A, 0x79, 0xDF, 0xDF, 0xF5, 0x5F, 0xB3, 0xEF, 0xFF, 0x4D, 0x52, 0xD5, 0x6F, 0x3E, 0x02, + 0x58, 0xDA, 0xC8, 0xFA, 0x31, 0x2D, 0xF1, 0x3F, 0xAB, 0x75, 0x25, 0x5B, 0x31, 0x7D, 0x88, 0xB0, + 0x91, 0x39, 0x2C, 0x11, 0x6B, 0x81, 0x78, 0xCB, 0x92, 0xF3, 0xF5, 0x9B, 0x77, 0xA0, 0xB9, 0x75, + 0x62, 0xAA, 0xD2, 0x8E, 0xEC, 0x8F, 0x9D, 0x22, 0x64, 0x28, 0xA5, 0x37, 0x9A, 0xF7, 0x7B, 0x27, + 0xBD, 0x41, 0xEF, 0x45, 0xE7, 0x09, 0xB2, 0x1A, 0xA0, 0x32, 0x62, 0x9E, 0x94, 0xA4, 0x90, 0x3F, + 0xCA, 0xA3, 0x5A, 0xD1, 0x49, 0x52, 0x6E, 0xDA, 0xFA, 0xD8, 0x3F, 0x3F, 0xAB, 0x42, 0x13, 0x64, + 0xED, 0x5C, 0x1F, 0xCA, 0x3D, 0x14, 0xCA, 0xDA, 0x13, 0xFD, 0x21, 0x47, 0x94, 0xB5, 0x06, 0x4D, + 0xC1, 0x3F, 0xC3, 0xB8, 0x39, 0x0A, 0xCB, 0x33, 0xCB, 0x87, 0x1E, 0xDF, 0xFE, 0xC7, 0xA4, 0xF6, + 0xDE, 0x30, 0xFD, 0x96, 0x5A, 0xE2, 0x82, 0x4A, 0x49, 0x3E, 0x65, 0x23, 0x67, 0x66, 0x59, 0x89, + 0x7D, 0x56, 0x7B, 0x77, 0x14, 0xB0, 0x20, 0x06, 0xE5, 0x6D, 0xD8, 0xF2, 0xFB, 0x80, 0xC9, 0x96, + 0x2D, 0xFA, 0x4E, 0x99, 0x5D, 0x21, 0x84, 0xA1, 0xA7, 0x14, 0x53, 0x26, 0x86, 0x59, 0xA6, 0x19, + 0xD9, 0x09, 0x4E, 0x00, 0xE2, 0xC0, 0x77, 0xED, 0x03, 0xE1, 0x6B, 0xD9, 0x49, 0xC1, 0xAB, 0x49, + 0x67, 0xC2, 0xCE, 0x76, 0x2D, 0x62, 0x3A, 0x6A, 0xE2, 0xD6, 0x2F, 0x3C, 0x40, 0xF8, 0x3D, 0xB2, + 0x68, 0x96, 0x17, 0x65, 0x04, 0xD2, 0xDF, 0xEF, 0x64, 0x40, 0x59, 0x72, 0x8D, 0x41, 0x59, 0x5A, + 0x5D, 0x01, 0x89, 0xD9, 0x35, 0x06, 0xBC, 0x23, 0x0F, 0x84, 0x5F, 0x13, 0x58, 0x05, 0xAE, 0x4B, + 0xD0, 0xFA, 0xBF, 0x31, 0xEB, 0xAE, 0x02, 0xC4, 0x84, 0xFC, 0x4C, 0xD0, 0x9C, 0x3C, 0x1D, 0xE4, + 0x35, 0x7A, 0xD3, 0xE5, 0x24, 0xBF, 0xA2, 0x64, 0x70, 0x9D, 0xEF, 0xA6, 0x7E, 0xC1, 0x5B, 0x7C, + 0xA6, 0x91, 0x9B, 0xFF, 0x10, 0x28, 0xF6, 0xCD, 0xC4, 0x7E, 0xFC, 0xF0, 0x1B, 0x4B, 0xB9, 0xD8, + 0x82, 0x6A, 0x51, 0xB4, 0x82, 0xC3, 0xB2, 0x23, 0xC8, 0x2A, 0x3F, 0x80, 0x49, 0xE1, 0xF1, 0x31, + 0x33, 0x78, 0xDF, 0x36, 0x24, 0x76, 0x56, 0x79, 0x64, 0x31, 0x87, 0x0B, 0xE6, 0xD6, 0xCB, 0x6C, + 0x88, 0x66, 0x7E, 0x41, 0xC1, 0x86, 0xA9, 0x91, 0xE5, 0x22, 0x29, 0x44, 0x97, 0xB8, 0x90, 0xEF, + 0x36, 0xC0, 0xAA, 0x2A, 0x12, 0x9F, 0x61, 0x27, 0xCC, 0x73, 0x73, 0x16, 0xD3, 0xD0, 0xC9, 0xE4, + 0x60, 0x6C, 0x4A, 0x17, 0x46, 0x30, 0xFE, 0xC0, 0x24, 0xDF, 0x11, 0xAD, 0x7C, 0x95, 0x03, 0x8D, + 0x44, 0xA7, 0x55, 0xFC, 0x88, 0x4F, 0x2E, 0x76, 0xB2, 0x71, 0xED, 0x4F, 0x7A, 0xA8, 0xBF, 0x74, + 0x32, 0x1F, 0xF1, 0x1A, 0x4F, 0xFA, 0xB2, 0x82, 0xA7, 0xA7, 0x52, 0xC8, 0xF9, 0xF3, 0x9E, 0xEF, + 0x22, 0x6C, 0xC7, 0x72, 0x47, 0xDA, 0x17, 0x6C, 0xB8, 0x2D, 0x2B, 0xDF, 0x18, 0xD7, 0x4D, 0x6E, + 0xDD, 0xA7, 0xE2, 0x77, 0xD2, 0xF0, 0x4B, 0xCF, 0x7B, 0x73, 0x52, 0xD7, 0x8F, 0x5B, 0xF8, 0xFB, + 0xC7, 0x6F, 0x6B, 0x4F, 0x90, 0x7E, 0xE8, 0x04, 0x4A, 0x3E, 0x5D, 0x5A, 0x97, 0xEE, 0xC5, 0x62, + 0x3E, 0xA0, 0xFC, 0xF6, 0x4F, 0x7E, 0x76, 0x8F, 0x17, 0xCE, 0x58, 0x1D, 0x66, 0x31, 0xD4, 0xA4, + 0xAC, 0x13, 0x5D, 0x3A, 0x2C, 0x88, 0xFD, 0x3E, 0xBB, 0xF4, 0x27, 0x2D, 0xAE, 0x73, 0xDD, 0x91, + 0x25, 0xD1, 0x29, 0x1D, 0xFA, 0x56, 0xAC, 0xAD, 0xE7, 0x78, 0xE0, 0x33, 0x7C, 0x70, 0xC9, 0x62, + 0x4B, 0x98, 0x52, 0x21, 0xC0, 0x59, 0x48, 0x65, 0xFF, 0xB5, 0xF9, 0x3F, 0x8A, 0x33, 0x98, 0x1D, + 0x45, 0x8E, 0x8B, 0x55, 0x09, 0x36, 0xEA, 0xC3, 0xA8, 0x4C, 0x72, 0xD4, 0xD2, 0x29, 0x94, 0xC7, + 0x9A, 0x0A, 0x51, 0xA4, 0x66, 0xC3, 0x9B, 0x08, 0x57, 0x8C, 0x54, 0xA2, 0xC9, 0x01, 0x06, 0x43, + 0x0E, 0xC4, 0xE2, 0x22, 0x40, 0xB1, 0xA7, 0x0C, 0xF6, 0x17, 0x66, 0xD2, 0x3E, 0xDB, 0x1C, 0x35, + 0x59, 0x14, 0x3E, 0xE2, 0xD7, 0x32, 0x1F, 0x25, 0xA0, 0xEC, 0xE0, 0xC3, 0x80, 0xF6, 0xDD, 0x71, + 0x38, 0x20, 0xA3, 0x40, 0x8B, 0x85, 0x5B, 0x01, 0x0B, 0x40, 0x7D, 0x58, 0xA5, 0x6B, 0x9B, 0x19, + 0xE6, 0x0E, 0xCD, 0xC9, 0xD4, 0xC2, 0x3D, 0xBC, 0xB6, 0x8E, 0xF7, 0xE7, 0x4F, 0x20, 0x12, 0x2F, + 0xD1, 0x02, 0xB0, 0xFE, 0xD4, 0x9D, 0x5F, 0xF8, 0xA6, 0x13, 0x9E, 0xB2, 0x83, 0x46, 0x8D, 0x2D, + 0xCA, 0x64, 0x18, 0xDD, 0xB5, 0x6D, 0xE2, 0x18, 0x41, 0x15, 0x4A, 0xCC, 0x2E, 0x7F, 0xD7, 0x22, + 0xA3, 0xE3, 0xC4, 0x6D, 0x2A, 0x85, 0x80, 0xC0, 0x12, 0x83, 0x77, 0x15, 0xCA, 0xA2, 0x6B, 0x04, + 0x79, 0xEA, 0x98, 0x3E, 0x36, 0x95, 0x6F, 0x73, 0xBC, 0xDE, 0x5E, 0xE8, 0x86, 0xBE, 0x55, 0xE9, + 0x17, 0xCA, 0x78, 0xCD, 0x5B, 0xC7, 0x6F, 0x0E, 0x0F, 0x4D, 0x4F, 0x11, 0x0A, 0x56, 0x36, 0x4D, + 0x69, 0x4F, 0x88, 0x9F, 0x8B, 0x4B, 0xEB, 0x9A, 0x54, 0x24, 0x2C, 0x4B, 0x0A, 0xE1, 0x2E, 0x5D, + 0x2C, 0xA9, 0xAA, 0x88, 0x8A, 0x71, 0xD6, 0x8D, 0x68, 0xA3, 0xBB, 0x9D, 0x3B, 0xF8, 0x6B, 0x0D, + 0x4C, 0x40, 0xF4, 0x88, 0x17, 0x0A, 0x09, 0xE9, 0xCC, 0x7D, 0x96, 0x90, 0x37, 0xCB, 0x42, 0xDE, + 0xBC, 0x40, 0xC8, 0x3C, 0x33, 0xC3, 0xC7, 0x10, 0x86, 0x3F, 0x25, 0x0E, 0x99, 0x50, 0x1F, 0x1A, + 0x90, 0x19, 0xC9, 0x54, 0xBF, 0xB3, 0xA8, 0x3E, 0x7D, 0xA6, 0xA8, 0xFD, 0xA9, 0x39, 0x0E, 0xF3, + 0x04, 0x8E, 0x3A, 0x7E, 0x67, 0xB1, 0x91, 0xB1, 0x97, 0x8A, 0x1D, 0xC5, 0xAB, 0xB8, 0xD0, 0x49, + 0x6F, 0x84, 0xCA, 0xDB, 0x0C, 0x99, 0xEA, 0x5C, 0x94, 0x5C, 0xE9, 0x4B, 0x1D, 0xCF, 0x29, 0xA5, + 0x9E, 0x51, 0xEA, 0xFC, 0xB6, 0x10, 0x94, 0x23, 0xD5, 0x93, 0xB4, 0x8C, 0xE1, 0xF4, 0x70, 0x21, + 0x13, 0x47, 0x6D, 0xD7, 0xE9, 0xB8, 0xC6, 0xE3, 0x09, 0x9E, 0x61, 0xC6, 0x37, 0x4D, 0xE0, 0x3F, + 0x64, 0x14, 0xE5, 0xDB, 0x53, 0x54, 0x3C, 0xC1, 0xFA, 0x2B, 0xC4, 0x16, 0xB0, 0xB0, 0xE1, 0xCE, + 0x41, 0x43, 0x3A, 0xDB, 0x67, 0xAD, 0x4E, 0x7D, 0x3A, 0x06, 0xDD, 0x03, 0xBB, 0x3A, 0xD5, 0x6A, + 0x5F, 0xDE, 0xFF, 0xED, 0xB6, 0x04, 0x2B, 0x92, 0x16, 0x3C, 0x8A, 0x2D, 0x78, 0xF9, 0xDB, 0xED, + 0xDF, 0x8B, 0xB5, 0x89, 0x59, 0x4E, 0x14, 0x69, 0x97, 0xEF, 0xE9, 0x63, 0x99, 0xDF, 0xE3, 0x82, + 0x94, 0x8F, 0x03, 0x7D, 0x81, 0x96, 0x5B, 0xA0, 0xCD, 0x1A, 0x77, 0x84, 0x6D, 0x52, 0x15, 0x5B, + 0x6A, 0xA9, 0x15, 0xE5, 0xC8, 0x32, 0x43, 0xAE, 0xF2, 0x09, 0xCF, 0x5E, 0xF9, 0xAA, 0x8B, 0xBD, + 0x26, 0xC1, 0x36, 0xBA, 0x04, 0x13, 0x93, 0x61, 0x57, 0x6C, 0x54, 0x6C, 0x52, 0xE3, 0x1B, 0x36, + 0x08, 0x98, 0x73, 0x2F, 0x59, 0x8D, 0x2E, 0xA2, 0xAB, 0x99, 0xAB, 0xC9, 0xA0, 0xC0, 0x1D, 0xBC, + 0xE3, 0x2C, 0xEE, 0x36, 0x8B, 0x4B, 0xCE, 0xFC, 0x6E, 0x07, 0xEA, 0x3F, 0x68, 0xD6, 0x6A, 0xBA, + 0xE1, 0xDC, 0x05, 0x90, 0x3A, 0xDD, 0x99, 0x31, 0xB6, 0x60, 0xF9, 0x8A, 0xD3, 0xAB, 0x46, 0xEE, + 0xC8, 0x02, 0xD6, 0xA8, 0xA3, 0xA0, 0x86, 0xC6, 0x6B, 0x54, 0x1B, 0xD5, 0x77, 0xF8, 0x56, 0x85, + 0xF5, 0x90, 0xFC, 0x4B, 0x64, 0xD2, 0x8A, 0x48, 0x81, 0x24, 0x08, 0xAB, 0xF4, 0xB0, 0xA5, 0xCE, + 0xC2, 0x71, 0xE5, 0xAD, 0xBA, 0x27, 0x0D, 0x5B, 0x13, 0xBF, 0x9E, 0x86, 0x87, 0x27, 0x60, 0x47, + 0x76, 0x15, 0x46, 0x95, 0xED, 0xB9, 0xA3, 0xEE, 0x81, 0x64, 0xBB, 0x86, 0xF9, 0xA0, 0x98, 0xD0, + 0x15, 0x8B, 0x03, 0x44, 0xA0, 0x2D, 0xD5, 0xC7, 0x14, 0x92, 0xD3, 0x2E, 0xB4, 0x9D, 0xD3, 0x13, + 0x15, 0x3B, 0xD1, 0x85, 0x95, 0xE8, 0x0A, 0x0A, 0xFB, 0x35, 0x1F, 0x19, 0xC1, 0x64, 0x97, 0x77, + 0x10, 0x27, 0x7D, 0x9D, 0x47, 0x20, 0x16, 0x52, 0x88, 0x05, 0x40, 0xE4, 0x08, 0x28, 0x20, 0x4A, + 0xC6, 0x04, 0x65, 0xBF, 0x9F, 0xF7, 0x5F, 0xFE, 0x90, 0xAA, 0x9A, 0xB0, 0x37, 0x00, 0x00 +}; + class SPIFFSEditor: public AsyncWebHandler { private: String _username; String _password; - bool _uploadAuthenticated; + bool _authenticated; + uint32_t _startTime; public: - SPIFFSEditor(String username=String(), String password=String()):_username(username),_password(password),_uploadAuthenticated(false){} + SPIFFSEditor(String username=String(), String password=String()):_username(username),_password(password),_authenticated(false),_startTime(0){} bool canHandle(AsyncWebServerRequest *request){ - if(request->method() == HTTP_GET && request->url() == "/edit" && (SPIFFS.exists("/edit.htm") || SPIFFS.exists("/edit.htm.gz"))) + if(request->method() == HTTP_GET && request->url() == "/edit") return true; else if(request->method() == HTTP_GET && request->url() == "/list") return true; - else if(request->method() == HTTP_GET && (request->url().endsWith("/") || SPIFFS.exists(request->url()) || (!request->hasParam("download") && SPIFFS.exists(request->url()+".gz")))) + else if(request->method() == HTTP_GET && !(request->url().endsWith("/")) && request->hasParam("download")) return true; else if(request->method() == HTTP_POST && request->url() == "/edit") return true; @@ -31,11 +298,13 @@ class SPIFFSEditor: public AsyncWebHandler { } void handleRequest(AsyncWebServerRequest *request){ - if(_username.length() && (request->method() != HTTP_GET || request->url() == "/edit" || request->url() == "/list") && !request->authenticate(_username.c_str(),_password.c_str())) + if(_username.length() && _password.length() && !request->authenticate(_username.c_str(), _password.c_str())) return request->requestAuthentication(); if(request->method() == HTTP_GET && request->url() == "/edit"){ - request->send(SPIFFS, "/edit.htm"); + AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", edit_htm_gz, edit_htm_gz_len); + response->addHeader("Content-Encoding", "gzip"); + request->send(response); } else if(request->method() == HTTP_GET && request->url() == "/list"){ if(request->hasParam("dir")){ String path = request->getParam("dir")->value(); @@ -43,7 +312,7 @@ class SPIFFSEditor: public AsyncWebHandler { path = String(); String output = "["; while(dir.next()){ - File entry = dir.openFile("r"); + fs::File entry = dir.openFile("r"); if (output != "[") output += ','; bool isDir = false; output += "{\"type\":\""; @@ -60,13 +329,10 @@ class SPIFFSEditor: public AsyncWebHandler { else request->send(400); } else if(request->method() == HTTP_GET){ - String path = request->url(); - if(path.endsWith("/")) - path += "index.htm"; - request->send(SPIFFS, path, String(), request->hasParam("download")); + request->send(SPIFFS, request->url(), String(), true); } else if(request->method() == HTTP_DELETE){ if(request->hasParam("path", true)){ - ESP.wdtDisable(); SPIFFS.remove(request->getParam("path", true)->value()); ESP.wdtEnable(10); + SPIFFS.remove(request->getParam("path", true)->value()); request->send(200, "", "DELETE: "+request->getParam("path", true)->value()); } else request->send(404); @@ -81,9 +347,9 @@ class SPIFFSEditor: public AsyncWebHandler { if(SPIFFS.exists(filename)){ request->send(200); } else { - File f = SPIFFS.open(filename, "w"); + fs::File f = SPIFFS.open(filename, "w"); if(f){ - f.write(0x00); + f.write((uint8_t)0x00); f.close(); request->send(200, "", "CREATE: "+filename); } else { @@ -97,25 +363,31 @@ class SPIFFSEditor: public AsyncWebHandler { void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){ if(!index){ - if(!_username.length() || request->authenticate(_username.c_str(),_password.c_str())) - _uploadAuthenticated = true; - request->_tempFile = SPIFFS.open(filename, "w"); + if(!_username.length() || request->authenticate(_username.c_str(),_password.c_str())){ + _authenticated = true; + request->_tempFile = SPIFFS.open(filename, "w"); + _startTime = millis(); + } } - if(_uploadAuthenticated && request->_tempFile && len){ - ESP.wdtDisable(); request->_tempFile.write(data,len); ESP.wdtEnable(10); + if(_authenticated && request->_tempFile){ + if(len){ + request->_tempFile.write(data,len); + } + if(final){ + request->_tempFile.close(); + uint32_t uploadTime = millis() - _startTime; + os_printf("upload: %s, %u B, %u ms\n", filename.c_str(), index+len, uploadTime); + } } - if(_uploadAuthenticated && final) - if(request->_tempFile) request->_tempFile.close(); } }; - // SKETCH BEGIN AsyncWebServer server(80); - AsyncWebSocket ws("/ws"); +AsyncEventSource events("/events"); -void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ +void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ if(type == WS_EVT_CONNECT){ os_printf("ws[%s][%u] connect\n", server->url(), client->id()); client->printf("Hello Client %u :)", client->id()); @@ -159,7 +431,7 @@ void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp } os_printf("ws[%s][%u] frame[%u] %s[%llu - %llu]: ", server->url(), client->id(), info->num, (info->message_opcode == WS_TEXT)?"text":"binary", info->index, info->index + len); - + if(info->opcode == WS_TEXT){ for(size_t i=0; i < info->len; i++) { msg += (char) data[i]; @@ -193,25 +465,9 @@ const char* password = "*******"; const char* http_username = "admin"; const char* http_password = "admin"; - -extern "C" void system_set_os_print(uint8 onoff); -extern "C" void ets_install_putc1(void* routine); - -//Use the internal hardware buffer -static void _u0_putc(char c){ - while(((U0S >> USTXC) & 0x7F) == 0x7F); - U0F = c; -} - -void initSerial(){ - Serial.begin(115200); - ets_install_putc1((void *) &_u0_putc); - system_set_os_print(1); -} - void setup(){ - initSerial(); - SPIFFS.begin(); + Serial.begin(115200); + Serial.setDebugOutput(true); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); if (WiFi.waitForConnectResult() != WL_CONNECTED) { @@ -220,18 +476,40 @@ void setup(){ delay(1000); WiFi.begin(ssid, password); } - ArduinoOTA.begin(); - //Serial.printf("format start\n"); SPIFFS.format(); Serial.printf("format end\n"); - ws.onEvent(onEvent); + //Send OTA events to the browser + ArduinoOTA.onStart([]() { events.send("Update Start", "ota"); }); + ArduinoOTA.onEnd([]() { events.send("Update End", "ota"); }); + ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { + char p[32]; + sprintf(p, "Progress: %u%%\n", (progress/(total/100))); + events.send(p, "ota"); + }); + ArduinoOTA.onError([](ota_error_t error) { + if(error == OTA_AUTH_ERROR) events.send("Auth Failed", "ota"); + else if(error == OTA_BEGIN_ERROR) events.send("Begin Failed", "ota"); + else if(error == OTA_CONNECT_ERROR) events.send("Connect Failed", "ota"); + else if(error == OTA_RECEIVE_ERROR) events.send("Recieve Failed", "ota"); + else if(error == OTA_END_ERROR) events.send("End Failed", "ota"); + }); + ArduinoOTA.begin(); + + SPIFFS.begin(); + + ws.onEvent(onWsEvent); server.addHandler(&ws); - - server.serveStatic("/fs", SPIFFS, "/"); + + events.onConnect([](AsyncEventSourceClient *client){ + client->send("hello!",NULL,millis(),1000); + }); + server.addHandler(&events); + + server.addHandler(new SPIFFSEditor(http_username,http_password)); + server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html"); server.on("/heap", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(200, "text/plain", String(ESP.getFreeHeap())); }); - server.addHandler(new SPIFFSEditor(http_username,http_password)); server.onNotFound([](AsyncWebServerRequest *request){ os_printf("NOT_FOUND: "); diff --git a/examples/ESP_AsyncFSBrowser/data/edit.htm.gz b/examples/ESP_AsyncFSBrowser/data/edit.htm.gz deleted file mode 100644 index 9ee1b81f0054db18190d447db26b3a7a15f10e88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4116 zcmb2|=HQqn6&K3DoSKqZqL)#U%P=>xvV4)3*#G~vTynO?hgN9JSZk`X_?XUI+pJxi z&(2};a=6JP;j6R%_nqhl!# z?vxBpSv2F{qqVQt#O9hyf34Ey5;iYAyuhd^Gw-ri}BXF6ruFCSPnYoYkDv-<6`e_Y>mN9EIrY-0{)t}UOl9tmjAF@5b68}Ryo z$~Io5tJ*)7=bTs@D6!<~k=n(+q0E_ktd;h?-fJc-q;j?8*gFmBd4bo z>&opP?yz)ReBcu&<#x7eS=HXBlW&wUXSf{Mbmu@`TFSiL5s}it{Y&0)=l;wKn7cFV zmC1I8sP3&Kq*D}pk+F4d-h-WtYo+2c{K6(}TU4pH`elp0N!*^@ z-NE%U{v6nK{k87YFR5JDLVrkK)%{X${&Mm|$xdmP%OxL+H4b;o$otjx?eHenUqUOA z=2tNNirKMrqbpNT=5f7`T7S#ehyVSs)~eO)i*44jnUfXyjveu>pZ6m(;cV<3Pd_n- zsk_-tpG`}53+*-Vb)N5>m%8CV;O5W4E_HAJnts#$ko{`bk<~)yw>B?(A2rSWdcf^D z$L6I>oMI9?|Hc+ER)y(YUhFaLgi_We1xR8`CU zetvyhdR$Uwe@sP6U18$BpQ-&ddu1wA!rH@jhrP>s+iSA#B^!HhVg2&UfzFR3t!L%P z@@`+(`?{=tv9U_|-`C$V4j0V1eEHzQt99MCr*HnY$2>=Vx_|Za(yjH^H=N&|Hh0PO zeebTk%};Mi-jCylt9I9xdGhb(Em}46{=xr;B1?RtN1i+XysW_IQd-Rs-8Zu_{ebajpHv)}O{TxZy`U%vC^()-K& zFveq^WEfXUXVlY~y9`*a>Fy7R4wWe3QS6+Jjcuh>yHlNtoZTBpjYf`k_tF{CwEiiuAc582?3ggs3 zt;Gk7^25B!Jl7R;h3OeZc`a>Q5IHGSGBl@hqo&1L--B1TPl*sR)jFjc9{6y|;vm7O zs1@fQl(PI?cjH!2oQijt(8;NdX?xs^!~9A&J`A~xZ{XSGo8rH{#--oLtK`r|UrR?MaL8y!_>M?bV-k_0zA0 z2wi>RsN=j}$Ig^Bhxh5Vn@LMn*k-O-@~LPi%dce3N#cEWqHL4y6itziUE7?)#Jq}A z*(Fey(|4tdMJ?+ul_b|Se+4#H>k3xB)I46roV>d?XR4b*XP3t7U2&mLpNnxgBZ5r;uq+|L(s!MeajI!2E<;EtyZ}8=d+5a_i3Am%aw|*T05WI+hf7 z#wx$g^Je1^zUncBw?Z=MwaW!#8K0koe{QSJ5&0TuoE) z1?|aCCG(5f{U5OG*|urTDTDrlSIm}r9(B(6ZFR`y%D%3SB?|7BII0>K9n5EZtJ3_0 zrBOs-f(g4%^aF_o!xd(3{i=}{ZLSo@bAQ>^k?^tGbkVEMO+^c0nk=^`ojyO?`i9Gr zcUkM11iJf|8fn^3`?i&jXWG_zi)6iwcsdR-Y6Py&I_~THyW0D}v&?&YGPBBcA8uOt zZi~ypZQmoDPD=@`l*pJl^Y$i1B`qNz!`V$!c~@nu<7}SBBN(JUiSg!1rq&~Of5s*6 zi=O?yQ+Kt){Pqr$f~V6yg$9Ni{9)>S_wH({jHRQFu3^=y&+LA;z6h&-I354#rik18 zDKZD&Pj7nceXKB~pe5svsJp@Ke@8AJ%biv{CspRH=<$#7uQ}@Gd2IP~^0M;A0>gm5 zZ=1u5y#x6l+&%TCNzr=t#?O+oUoV%_S`~aOlrMjGDz^zMOVQ5@E_ZCEU75RQaqMfe z1J1UZznJf8{%T;{?DRye>*V8iuMXs#2sSd=r~F#}=&|JrmDk&}Sl-*7)Z1;8zk9de zw|kT4e2O?Wwf>2avH!&T0@b3zwVU`%xP$hqc(%Nct&A6$?V|TM&GgANty{%{i|?#> z&9>&b;r4r*=I2cSK3YqEG=OEaOmUW zH&+)J9p{N~3^+1h?ebQhl}bY5){Ck%&B_g&AARPUua+P8`8jX>x1-NCUx?G2-zw=< z_3yt*=J`1{S?#t~^e(k(NaDE1vW}6(Cg6(V6tNmHiVB!^aVt~+qbTAwSHqxIZ` zi^}DZaetOpSpPGx;8CfJ@Z&;AbI zv%dE9?=&-6@yple|B~^#C0ReOSjA;eZJ@)M1|hx*g9=%B#TW6el`OZTc86?edc0vS zzrMoC)(!nXqtxX~9A>Z1nH#;P_@f5L%>!+Temqd*HrwKOx3IGt^I$^bGC2XyXMO*o7jf? z?xKrKaxBhu6lhJIF1q#d99{d*#r7X}$3HILf2=>{*v}Qq*t7mJTK^Ze{`!LX_?q9| z%N|-?cGht@P-%R+R(bB0qKNHw2fm%R>9^T%$wy&Mug57ro^Dn4xW|#1N4%5+rB;Si z-}rw#Sh8#%pMGTfG5dM{G_Olt_HzETd2`!Ohj}H*GpDL}sBx_7TDd|*u2;MwBP}fG zVS~0=S`up+_n!&ETRmE~I6L+RrFyTv9S;NUHQzRFD zJ!SWA_V0Uzv)p=8_lwSy44!l;u1xumhsebPuMXu0a$8gdpL#G|eRJk4{TF-YMdY~H zJm}r-$n(C|Ezd!>P5kAKRcG`DA=VYCRDAn zWOV)Wp*79uuEK(kA0Pbb*(tVIgDvHI=A;F^%g%rL?IYGSONTMEky|2R?;?*ZE0qnJ z$@b^YUpOZH%Vw!37tgKM=e7)g-{LkNgs>bG~vd`2qjwnt_oo*5HF0}0Cp{AA37w$@b z(0173OQCGJX`K|~E#Wxkz9Rp>O5b~CbJZt2|C`&$a2m#qw)Gjqq&h+ zUQ6*DnlkS}`s~w!RV;3ORm>OmPncQDlce>4q3OZG;B%PP zQl2&ORi*EB?BBWX?7px1`V#wtlm8nYTr9zRy7wky-ZX_djmzCxQd0FEOz+jHow>=d zQt@W2-03_U#_IwbPIM~NC5Zi>b_r-^aspkGEfyxOQf7#R)H$1a9@3$l7`go0U(yn1_1?s>M; zEr?muG&FGP`Wr#VI(Phg`Bm0v5rY`hlc3l+%ND=t+wom*>$KX7M;EEJ$ZXy9BTr$@ zx&*^FS_fM{GX3`8Pkt|)@zB3HQtxl3#rJH9g2<{Sy$ima0~tA d5X!Wwhe0ZXb5`s8_4U8?L#lc&oR?!@0043c=^p?9 diff --git a/examples/ESP_AsyncFSBrowser/data/graphs.js.gz b/examples/ESP_AsyncFSBrowser/data/graphs.js.gz deleted file mode 100644 index e0e13f69ea4c4fcb968dec7efaea5bcb8e8e9b63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2379 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 Sf4eT#Gbs4oy<;Q7zyJVaSCzB? diff --git a/examples/ESP_AsyncFSBrowser/data/index.htm b/examples/ESP_AsyncFSBrowser/data/index.htm index b9aea57..28f47e9 100644 --- a/examples/ESP_AsyncFSBrowser/data/index.htm +++ b/examples/ESP_AsyncFSBrowser/data/index.htm @@ -1,8 +1,8 @@ -